Неправильная работа joiner`a
Доброе время суток. Делаю простейшую программу по шифрованию теста. Нужно каждых два символа поменять местами и переместится на два символа вперёд (по отношению к первому). Код, который это делает, работает, но в JTextArea выводиться только конечных два символа (предполагаю, что это из-за цикла while, но не понимаю, почему joiner не может объединить все пузырьки в один текст последовательно и вывести preResult).
P.S System.out.print выводит всё корректно.
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.StringJoiner;
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setSize(500,417);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
JPanel panel = new JPanel();
panel.setLayout(null);
frame.add(panel);
JTextArea input_text = new JTextArea();
input_text.setBounds(5,5,475, 150);
input_text.setWrapStyleWord(true);
input_text.setLineWrap(true);
panel.add(input_text);
JTextArea output_text = new JTextArea();
output_text.setBounds(5,220,475, 150);
output_text.setWrapStyleWord(true);
output_text.setEditable(false);
output_text.setLineWrap(true);
panel.add(output_text);
JButton crypt_button = new JButton("Crypt");
crypt_button.setBounds(10,163,100,50);
panel.add(crypt_button);
JButton uncrypt_button = new JButton("Uncrypt");
uncrypt_button.setBounds(375,163,100,50);
panel.add(uncrypt_button);
crypt_button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent actionEvent) {
String text = input_text.getText();
int lenght = text.length();
int x = 0;
int y = 1;
String inter_x_1 = null;
String inter_y_2 = null;
int counter = 0;
while (counter < lenght) {
char x_1 = text.charAt(x);
inter_x_1 =String.valueOf(x_1);
char y_2 = text.charAt(y);
inter_y_2 =String.valueOf(y_2);
x+=2;
y+=2;
counter += 2;
StringJoiner joiner = new StringJoiner("");
joiner.add(inter_y_2 + inter_x_1);
String bubble = joiner.toString();
StringJoiner joiner_1 = new StringJoiner("");
joiner_1.add(joiner_1 + bubble);
String preResult = joiner_1.toString();
output_text.setText(preResult);
System.out.print(preResult);
}
}
});
frame.setVisible(true);
}
}
Ответы (1 шт):
System.out.print выводит последовательно все пары в поток вывода.
Когда выполняется output_text.setText(preResult);, то в текстовый компонент записывается только последняя пара переставленных букв.
Для аналогии с System.out.print можно было бы добавлять текст:
output_text.setText(output_text.getText() + preResult);
Или накапливать результат в экземпляре StringBuilder и затем записать его после цикла while:
StringBuilder sb = new StringBuilder();
while (counter < lenght) {
// ...
// output_text.setText(preResult); // убрать эту строку
sb.append(preResult);
}
output_text.setText(sb.toString());
В целом, сама реализация данной задачи может быть значительно упрощена, так как нет никакой необходимости использовать два джойнера и постоянные преобразования в строку, если можно просто в цикле просто добавлять в StringBuilder переставленные пары символов.
Кроме того, в показанном коде может возникнуть исключение StringIndexOutOfBoundsException, когда длина входной строки -- нечётное число.
Примерная реализация:
private static String encryptGood(String text) {
StringBuilder sb = new StringBuilder();
int n = text.length() - 1;
for (int i = 0; i < n; i += 2) {
sb.append(text.charAt(i + 1)).append(text.charAt(i));
}
if (n % 2 == 0) { // добавить последний оставшийся символ при нечётной длине
sb.append(text.charAt(n));
}
return sb.toString();
}
Тесты:
for (String txt : Arrays.asList("AB", "x", "TestEncrypt")) {
System.out.println("encrypt(" + txt+ ") = " + encryptGood(txt));
}
Результаты:
encrypt(AB) = BA
encrypt(x) = x
encrypt(TestEncrypt) = eTtsnErcpyt
Тогда обработчик actionPerformed может быть переписан как:
public void actionPerformed(ActionEvent ae) {
output_text.setText(encryptGood(input_text.getText()));
}