Визуализация сортировки выбором, java, swing
Есть задача - сделать визуализацию сортировки. Есть идея как это реализовать: есть класс ArrayVisualization, в котором происходит вызов метода класса ArrayElem, все это рисует массив, при вызове метода ArrayElem я сохраняю координату элемента в список. Мне нужно каким-то образом из класса Sort на каждом шаге с паузой выделять элемент(закрашивать прямоугольник с элементом), с которым происходит работа. Ноль идей как это сделать, т.к. все приходит к тому, что мне нужна переменная класса Graphics. Сейчас все работает, кроме самой визуализации, т.е. осортированный массив я отрисовываю.
Вопрос: Как это можно реализовать? Правильным ли я пошел путем? Как все это дело можно сделать вместе с Timer'ом? Возможно не нужно изменять отдельные элементы, а сразу отрисовывать весь массив? Новенький в java, надеюсь на помощь! Код:
Visualizaiton.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.Random;
public class Visualization extends JPanel{
private static final long serialVersionUID = 1L;
public ArrayVisualization arrVis;
public Sort sort;
private JButton resetArray;
private JButton startVis;
private JButton randomArr;
private JPanel buttonPanel;
private AddElem addElem;
private int x = 150;
private int y = 80;
public Visualization() {
arrVis = new ArrayVisualization();
resetArray = new JButton("Отчистить массив");
startVis = new JButton("Начать сортировку");
randomArr = new JButton("Сгенерировать массив");
buttonPanel = new JPanel();
addElem = new AddElem(arrVis);
buttonPanel.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridy = 0;
gbc.insets = new Insets(5, 10, 5, 25);
gbc.fill = gbc.HORIZONTAL;
gbc.weightx = 1;
resetArray.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
arrVis.arr.clear();
arrVis.repaint();
}
});
randomArr.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
arrVis.arr = generateRandomArray();
arrVis.repaint();
}
});
startVis.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
sort = new Sort(arrVis);
sort.selectionSort();
arrVis.arr = sort.arr;
arrVis.repaint();
}
});
buttonPanel.add(addElem, gbc);
buttonPanel.add(startVis, gbc);
buttonPanel.add(randomArr, gbc);
buttonPanel.add(resetArray, gbc);
setLayout(new BorderLayout());
add(arrVis);
add(buttonPanel,BorderLayout.SOUTH);
}
public ArrayList generateRandomArray(){
ArrayList arr = new ArrayList();
Random random = new Random();
while (arr.size() <= 10){
arr.add(random.nextInt(100)-50);
}
return arr;
}
}
ArrayVisualization.java
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
public class ArrayVisualization extends JPanel {
private static final long serialVersionUID = 1L;
public ArrayList<Integer> arr;
private int x = 150;
private int y = 80;
public ArrayList<Integer> elemCoords;
public ArrayVisualization() {
elemCoords = new ArrayList<>();
this.arr = new ArrayList<>();
setLayout(new BorderLayout());
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
elemCoords.clear();
x = 150;
g.setColor(Color.BLACK);
g.setFont(new Font("TimesRoman", Font.PLAIN, 30));
int widthOfDef = g.getFontMetrics().stringWidth("array = ");
g.drawString("array = ", x - widthOfDef - 10, y);
for (int i = 0;i<arr.size();i++){
int element = arr.get(i);
ArrayElem arrElem = new ArrayElem(x,this.getBackground(),element);
elemCoords.add(arrElem.paintComponent(g));
int width = g.getFontMetrics().stringWidth(Integer.toString(element));
x += width + 20;
}
}
}
ArrayElem.java
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
public class ArrayElem {
public int x;
public Color color;
public final int y = 80;
public int element;
public ArrayElem(int x, Color color, int element){
this.x = x;
this.color = color;
this.element = element;
}
public int paintComponent(Graphics g){
g.setFont(new Font("TimesRoman", Font.PLAIN, 30));
int width = g.getFontMetrics().stringWidth(Integer.toString(element));
g.setColor(color);
g.fillRect(x-10,y-40,width+20,60);
g.setColor(Color.BLACK);
g.drawRect(x-10,y-40,width+20,60);
g.drawString(Integer.toString(element),x,y);
return x;
}
}
Sort.java
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
public class Sort {
public ArrayVisualization arrVis;
public ArrayList<Integer> arr;
public ArrayList<Integer> elemCoords;
private Timer timer;
public Sort(ArrayVisualization arrVis){
this.arr = arrVis.arr;
this.arrVis = arrVis;
this.elemCoords = arrVis.elemCoords;
}
public void selectionSort() {
for (int i = 0; i < arr.size(); i++) {
int min = i;
ArrayElem arrElem = new ArrayElem(elemCoords.get(min),new Color(255,0,0),arr.get(min));
for (int j = i + 1; j < arr.size(); j++) {
ArrayElem arrElem2 = new ArrayElem(elemCoords.get(j),new Color(0,100,0),arr.get(j));
if (arr.get(j) < arr.get(min)) {
ArrayElem arrElem3 = new ArrayElem(elemCoords.get(j),new Color(0,255,100),arr.get(j));
min = j;
}
}
int helper = arr.get(i);
arr.set(i,arr.get(min));
arr.set(min,helper);
ArrayElem arrElem4 = new ArrayElem(elemCoords.get(min),new Color(0,0,255),arr.get(min));
}
}
}
AddElem.java
import javax.swing.*;
import javax.swing.border.Border;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import static javax.swing.JOptionPane.showMessageDialog;
public class AddElem extends JPanel {
private String element;
public final JButton inputButton = new JButton("Добавить элемент в массив");
public final JTextArea editTextArea = new JTextArea(1, 6);
public final JTextArea uneditTextArea = new JTextArea();
public ArrayVisualization arrVis;
public AddElem(ArrayVisualization arrVis) {
this.arrVis = arrVis;
setLayout(new GridLayout(1, 2));
uneditTextArea.setEditable(false);
Border border = BorderFactory.createLineBorder(Color.BLACK);
editTextArea.setBorder(BorderFactory.createCompoundBorder(border, BorderFactory.createEmptyBorder(1, 1, 1, 1)));
add(uneditTextArea, BorderLayout.CENTER);
add(editTextArea, BorderLayout.SOUTH);
add(inputButton, BorderLayout.WEST);
inputButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
element = editTextArea.getText();
editTextArea.setText("");
if (arrVis.arr.size() <= 10) {
try {
arrVis.arr.add(Integer.parseInt(element));
arrVis.repaint();
}
catch (NumberFormatException ex){
showMessageDialog(null, "Некорректные данные");
}
}
}
});
setVisible(true);
}
}
Фулл код(если вдруг нужен):https://github.com/kirinzx/selectionSortVisualization P.S. код в классе Sort, где я пытаюсь выделить элементы, для наглядности того, что я хочу сделать