首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >非所需java.awt矩形动画

非所需java.awt矩形动画
EN

Stack Overflow用户
提问于 2017-01-13 14:20:23
回答 1查看 79关注 0票数 1

我试图动画的选择和插入排序算法的过程,矩形显示排序值的高度。

当选择/插入排序算法中发生单个更改时,我调用repaint(),但它似乎没有完全重新绘制它们,只是部分矩形发生了更改。在最终结果中,它实际上根本不显示完全排序的数组。

这两种算法都经过测试和工作,因此问题似乎与动画他们的过程。

有什么帮助吗?

MyPaint.java

代码语言:javascript
运行
复制
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

代码语言:javascript
运行
复制
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; 
        }
}
EN

Stack Overflow用户

回答已采纳

发布于 2017-01-13 16:56:18

首先,您不应该重写JFrame的paint方法。而是重写用于自定义绘图的paintComponent()JPanel。为此,您可以使用MyPanel

代码语言:javascript
运行
复制
public class MyPanel extends JPanel{

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

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

}

其次,避免使用空布局。最好在您的情况下为BorderLayout使用类似JFrame的东西。

此外,您还必须了解事件调度线程。对GUI元素的操作必须发生在这个线程上。

您应该在EDT上设置GUI。您可以在主方法中使用SwingUtilities.invokeLater()完成此操作:

代码语言:javascript
运行
复制
SwingUtilities.invokeLater(() -> {
    SortDriver frame = new SortDriver();
    mainArr = frame.getArr();
    frame.setVisible(true);
});

您应该考虑在单独的线程中处理动画,以便排序发生在EDT之外。下面是一个关于它如何在原则上以您的选择排序为特征的小演示:

代码语言:javascript
运行
复制
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();

如您所见,我将更新选择排序的代码放在一个synchronized块中,以便它与paintComponent()方法同步。这是必要的,因为绘制发生在EDT上,而排序发生在与EDT不同的线程上。在本例中,我使用MyPanel对象作为监视器。

票数 1
EN
查看全部 1 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41636669

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档