2017-01-13 6 views
1

選択のプロセスをアニメートしようとしています&ソートされた値を高さで表示する長方形の挿入ソートアルゴリズム。必要な機能を果たさないjava.awtの長方形のアニメーション

Select/Insertソートアルゴリズムで1回の変更が発生したときに私はrepaint()を呼び出しますが、完全に再描画するようには見えません。一部の矩形だけが変更されます。最終的には、完全にソートされた配列は実際には表示されません。

両方のアルゴリズムがテストされ、機能するため、問題はプロセスのアニメーション化にあるようです。

助けが必要ですか?

MyPaint.java

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 
import java.util.Timer; 
import java.util.TimerTask; 
public class MyPanel extends JPanel{ 
    private static int[] mainArr; 
    private boolean reset = false; 
    private Timer t = new Timer(); 
    private int[] tempArr; 
    public MyPanel(){ 
     JPanel panel = new JPanel(); 
     panel.setPreferredSize(new Dimension(400, 400)); 
     panel.setBackground(Color.WHITE); 
     panel.setLayout(new FlowLayout(FlowLayout.CENTER)); 
     //JButton selButton = new JButton("Select Sort"); 
     //panel.add(selButton); 
     add(panel);  
    } 
    public static void main(String[] args) { 
     SortDriver frame = new SortDriver(); 
     mainArr = frame.getArr(); 
     frame.setVisible(true); 

    } 
} 

SortDriver.java

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 
import java.awt.Graphics; 
public class SortDriver extends JFrame implements ActionListener { 

     private int modeName; 
     private JButton startButton; 
     private JButton selButton; 
     private JButton insButton; 
     private JPanel mainPanel; 
     private MyPanel panel; 
     private int[] sortArr = new int[41]; 

     public SortDriver() { 
       setLayout(null); 
       setPreferredSize(new Dimension(420, 420)); 
       setResizable(false); 
       setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       mainPanel = new JPanel(); 
       mainPanel.setBackground(Color.WHITE); 
       mainPanel.setBounds(0, 0, 420, 420); 
       mainPanel.setPreferredSize(new Dimension(400, 400)); 
       //mainPanel.setLayout(new FlowLayout(FlowLayout.CENTER)); 
       add(mainPanel); 

       //Buttons 
       startButton = new JButton("Start"); 
       startButton.addActionListener(this); 
       mainPanel.add(startButton); 
       selButton = new JButton("Select Sort"); 
       selButton.addActionListener(this); 
       mainPanel.add(selButton); 
       insButton = new JButton("Insert Sort"); 
       insButton.addActionListener(this); 
       mainPanel.add(insButton); 


       //Panel 
       panel = new MyPanel(); 

       mainPanel.add(panel); 
       //Array        
       for(int i = 0; i <= 40; i++){ 
        sortArr[i] = 0; 
       } 
       for(int i = 0; i <= 40; i++){ 
        int random = (int)(Math.random() * 50 + 1); 
        sortArr[i] = random; 
       } 
       //Final 
       pack(); 
     } 
     public void paint(Graphics g) { 
      for(int i = 0; i <= 40; i++){ 
      g.fillRect(i * 10, 100, 5, sortArr[i]); 
      }  
     } 

     public void selectionSort (int[] list){  
      int min;  
      int temp;   
      for (int index = 0; index < list.length-1; index++){   
      min = index;   
      for (int scan = index+1; scan < list.length; scan++)    
       if (list[scan] - (list[min]) < 0) min = scan;   

     // Swap the values   
      temp = list[min];   
      list[min] = list[index]; 
      list[index] = temp; 
      repaint(); 
      } 
      //for(int i = 0; i <= list.length; i++){ 
      // System.out.println(list[i]); 
      //} 
     } 
     public void insertionSort (int[] list){  
      for (int index = 1; index < list.length; index++){   
      int key = list[index];   
      int position = index;   

      // Shift larger values to the right   
      while (position > 0 && key - (list[position-1]) < 0){    
       list[position] = list[position-1]; 
       position--; 
       repaint(); 
      }   
      list[position] = key;  
      }  
     } 
     public void actionPerformed(ActionEvent event) { 
      if (event.getSource() == selButton) { 
      modeName = 1; 
      } 
      else if (event.getSource() == insButton) { 
      modeName = 2; 
      } 
      else if (event.getSource() == startButton) { 
      if(modeName == 1){ 
       selectionSort(sortArr); 
      } 
      if(modeName == 2){ 
       insertionSort(sortArr); 
      } 
      } 
     } 
     public int getMode(){ 
      return modeName; 
     } 
     public int[] getArr(){ 
      return sortArr; 
     } 
} 

答えて

1

まず第一に、あなたはあなたのJFrameのpaintメソッドをオーバーライドするべきではありません。カスタマイズ図面の場合は、JPanelpaintComponent()をオーバーライドします。この目的にはMyPanelを使用できます。

public class MyPanel extends JPanel{ 

    public MyPanel(){ 
     setBackground(Color.WHITE);    
    } 

    public synchronized void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     // your paint code  
    } 

} 

第2に、ヌルレイアウトを使用しないでください。 JFrameの場合は、BorderLayoutのようなものを使用してください。

また、Event Dispatch Threadに注意する必要があります。このスレッドでGUI要素の操作が行われなければなりません。

EDTにGUIを設定する必要があります。あなたは、あなたのメイン・メソッドでSwingUtilities.invokeLater()を使用してこれを行うことができます。

SwingUtilities.invokeLater(() -> { 
    SortDriver frame = new SortDriver(); 
    mainArr = frame.getArr(); 
    frame.setVisible(true); 
}); 

ソートがEDTの外で起こるようにするには、別のスレッドでアニメーションを処理するために検討すべきです。ここでは、それはあなたの選択ソートを搭載し、原則的に働く可能性がどのように小さなデモは次のとおりです。

new Thread(() -> { 
    int min;  
    int temp; 

    final int delayMillis = 100; 
    long startTickTime = System.nanoTime(); 
    for (int index = 0; index < list.length-1; index++){   
    synchronized(myPanel){ 
     min = index;   
     for (int scan = index+1; scan < list.length; scan++)    
      if (list[scan] - (list[min]) < 0) min = scan;   

     // Swap the values   
     temp = list[min];   
     list[min] = list[index]; 
     list[index] = temp; 
    } 
    myPanel.repaint(); 
    try { 
     TimeUnit.NANOSECONDS.sleep(delayMillis*1000000-System.nanoTime()+startTickTime); 
     startTickTime = System.nanoTime(); 
    } catch (Exception e) {     
     e.printStackTrace(); 
    } 
    } 
}).start(); 

あなたはそれがpaintComponent()方法と同期されるように、私は​​ブロックに選択ソートを更新するためのコードを入れて見ることができるように。これは、EDTとは異なるスレッドでソートが行われている間に、EDTでペイントが行われるため、必要です。この例では、モニタとしてMyPanelオブジェクトを使用しました。

関連する問題