私は、Javaプログラミングにおける新たなんだと私は、ソートの可視化を行うためにしようとしています。
あなたはJTextAreaのがあるトップ(リンク中)ウィンドウを表示することができますどのように、ここで私は私の配列を置くことができますし、プログラムの開発を入力して押すと、ボタンのマトリックスを構築します。プログラムは、すべての列のnボタンにペイントします。だから私は、グラフィカルに数字を表すことができます。バブルソートが押された場合、私は、ソートグラフィカルに配列をソートすることが、私はそれを行う際に、アニメーションクラスのsetBackgroundは何もしないバブルのアニメーションを見るようにしたいです。
私はスイングが短時間で再描画を複数回呼び出すことはできませんので、インターネットで見つけ、なぜ私は、タイマーを使用しました。
私の下にはGUIのリンクを置きます。
コード:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
class animation implements ActionListener{
private JButton grid[][];
private int i;
private int j;
private int N;
animation(JButton grid[][], int N, int i, int j){
this.grid=grid;
this.N=N;
this.i=i;
this.j=j;
}
public void actionPerformed(ActionEvent e){
JButton tmp[]=new JButton[N];
for(int y=0;y<N;++y){
tmp[y]=new JButton();
tmp[y].setBackground(grid[y][i].getBackground());
}
for(int y=0;y<N;++y){
grid[y][i].setBackground(grid[y][j].getBackground());
grid[y][j].setBackground(tmp[y].getBackground());
}
return;
}
}
class sortInterface extends JFrame implements ActionListener{
//components declaration
private ArrayList<Integer> arr=new ArrayList<Integer>();
private JPanel simulation=new JPanel();
private JButton grid[][];
private JPanel algorithm=new JPanel();
private JPanel frontPanel=new JPanel();
private JLabel title=new JLabel("SORTING ALGORITHMS", JLabel.CENTER);
private JTextField input=new JTextField();
private JButton enter=new JButton("ENTER");
private JButton bubble=new JButton("Bubble Sort");
private JButton insertion=new JButton("Insertion Sort");
private JButton selection=new JButton("Selection Sort");
private JButton quick=new JButton("Quick Sort");
private JButton merge=new JButton("Merge Sort");
//here start the GUI
private void setFrame(){
setLayout(new BorderLayout());
add(frontPanel, "North");
add(simulation, "Center");
add(algorithm, "South");
setSize(720, 480);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
return;
}
private void setFrontPanel(){
frontPanel.setLayout(new BorderLayout());
frontPanel.add(title, "North");
frontPanel.add(input, "Center");
frontPanel.add(enter, "South");
return;
}
private void setAlgorithm(){
algorithm.add(bubble);
algorithm.add(insertion);
algorithm.add(selection);
algorithm.add(quick);
algorithm.add(merge);
return;
}
private void setListeners(){
enter.addActionListener(new buttonHandler(simulation, arr, input));
bubble.addActionListener(new buttonHandler(simulation, arr, input));
return;
}
//here start the computational part
private boolean isNumber(char car){
if(car=='1'||car=='2'||car=='3'||car=='4'||car=='5'||car=='6'||car=='7'||car=='8'||car=='9'||car=='0')
return true;
return false;
}
private int convertSubStringToInt(String read, int i){
String tmp="";
while(isNumber(read.charAt(i))&&i<read.length()){
tmp=tmp+String.valueOf(read.charAt(i));
++i;
}
return (Integer.parseInt(tmp));
}
private void addElementToArray(String read){
boolean flag=true;
for(int i=0;i<read.length();++i){
if(read.charAt(i)==' ')
flag=true;
if(isNumber(read.charAt(i))&&flag){
arr.add(convertSubStringToInt(read, i));
flag=false;
}
}
return;
}
private int findMax(){
int maxIndex=0;
for(int i=1;i<arr.size();++i)
if(arr.get(maxIndex)<arr.get(i))
maxIndex=i;
return arr.get(maxIndex);
}
private void setSimulation(){
int max=findMax();
int constMax=max;
grid=new JButton[max][arr.size()];
simulation.removeAll();
simulation.revalidate();
simulation.repaint();
simulation.setLayout(new GridLayout(max, arr.size()));
for(int i=0;i<constMax;++i){
for(int j=0;j<arr.size();++j){
grid[i][j]=new JButton();
if(arr.get(j)>=max)
grid[i][j].setBackground(Color.white);
else
grid[i][j].setBackground(Color.black);
simulation.add(grid[i][j]);
}
--max;
}
simulation.validate();
return;
}
sortInterface(){
setFrame();
setFrontPanel();
setAlgorithm();
setListeners();
}
public void actionPerformed(ActionEvent e){
String read=e.getActionCommand();
if(read=="ENTER"){
arr.clear();
addElementToArray(input.getText()+" ");
setSimulation();
}
else if(read=="Bubble Sort"){
for(int i=0;i<arr.size()-1;++i)
for(int j=0;j<arr.size()-1-i;++j)
if(arr.get(j)>arr.get(j+1)){
int tmp=arr.get(j);
arr.set(j, arr.get(j+1));
arr.set(j+1, tmp);
Timer time=new Timer(1, new animation(grid, arr.size(), j, j+1));
time.start();
try{
Thread.sleep(200);
}
catch(Exception sleep){
//prova
}
time.stop();
}
}
else if(read=="Insertion Sort"){
}
else if(read=="Selection Sort"){
}
else if(read=="Quick Sort"){
}
else{
}
return;
}
}
class projSortInterface
{
public static void main(String argv[])
{
sortInterface prova=new sortInterface();
prova.setVisible(true);
return;
}
}
ジョニが言ったように、すべてのActionListenerがイベントディスパッチスレッドで呼び出されているので、あなたは、ActionListenerの中に眠るてはなりません。任意の大幅な遅延は、変更のいずれかを絵からスイングを防ぐことができます(また、任意のユーザーの入力に対する応答からスイングを防ぐことができます)。
しかし、あなたは可能で、あなたのロジックとあなたのスリープを実行する別のスレッド。あなたが覚えておく必要がある唯一のものは、メソッドをスイングし、コンストラクタをスイングするために呼び出しが別のスレッドで実行されないことです。別のスレッドで実行中に、あなたが使用する必要がありますEventQueue.invokeLaterを、それらのメソッド呼び出しを実行します。
新しいスレッドを使用して、それは次のようになります。
Runnable sortTask = () -> {
try {
for (int i=0; i < arr.size()-1; ++i) {
for (int j=0; j < arr.size()-1-i; ++j) {
if (arr.get(j) > arr.get(j+1)) {
int tmp = arr.get(j);
arr.set(j, arr.get(j+1));
arr.set(j+1, tmp);
int index1 = j;
int index2 = j+1;
EventQueue.invokeLater(() -> {
animation a =
new animation(grid, arr.size(), index1, index2);
a.actionPerformed(null);
});
Thread.sleep(200);
}
}
}
} catch (InterruptedException e) {
System.out.println("Interrupted. Terminating sort.");
}
};
new Thread(sortTask, "Sort").start();
あなたが見ることができるように、全体のソート操作は、新しいスレッドに渡されたRunnable、に移動されました。実際の「アニメーションは」に渡される別の小さなのRunnableで行われEventQueue.invokeLater
、それはSwingの操作が含まれており、イベントディスパッチスレッド以外のスレッドで実行することが許可されていないため、。
タイマーを使用してソートを達成することが可能であるが、それはあなたのロジックを見直し必要になります。あなたは使用することはできませんfor
ループを。私はスレッドを作成しての使用は保持考えるfor
より読みやすく、この場合での作業が容易になります。
他のいくつかの注意事項:
- try / catchであることに注意してください周り全体をソート。割り込みは事故によって発生しません。誰かがあなたのスレッドを中断した場合、それは彼らがするように求めていることを意味何をやっている停止きれいに可能な限り、終了します。プログラムはに実行を移動したときInterruptedExceptionあるが、ループを終了させることにより
catch
ブロック、あなたはこの要求を尊重しています。 - キャッチ決して
Exception
。NullPointerExceptionが、はIllegalArgumentException、とはIndexOutOfBoundsExceptionなどのプログラマのエラーを公開するために存在する未チェックの例外がたくさんあります。あなたは欲しい、彼らがエラーを公開するので、それらは、あなたのプログラムを終了することができている、プログラマ、修正する必要があります。それらを抑制することは、プログラムの仕事をすることはありません。 - ジョージ・Z.が指摘したように、文字列はオブジェクトであり、あなたが使用してオブジェクトを比較することはありません
==
それは、彼らが同じ値でいるかどうかを確認していないので、それは彼らがプログラム内の同じ場所に作成された同じオブジェクトであるかどうかを比較します。どのように私はJavaで文字列を比較するのですか?これを詳細に説明します。(それはしてオブジェクトを比較しても安全ですいくつかの特殊なケースがあり==
ますが、文字列は間違いなく彼らの中ではありませんが。) index1
そしてindex2
唯一の最後の変数は、内部クラスとラムダに渡すことができるので、変数が必要とされています。彼らは、と宣言する必要はありませんfinal
(それが許可されているが)。彼らはただである必要は、効果的に、最終的な彼らは一度だけ値が割り当てられているので、彼らがいます。