1

我正在创建一个 Java swing 应用程序 - 排序和搜索算法的动画。我用 JDeveloper 11g release2 编写了代码,默认情况下使用 jdk 1.6,该应用程序运行良好,但部署后我尝试在我的计算机上运行它,巫婆有 jdk 1.7,应用程序在随机时刻冻结并且无法恢复。我在每个人身上尝试了不同的 pc 和操作系统,该应用程序在 java 6 上运行良好,但如果使用 java 7 启动就会卡住。我尝试调试它,但调试器冻结为喜欢该应用程序,直到我用 Windows 关闭它才解冻任务管理器。

我设法追踪到应用程序在尝试设置文本时冻结在方法 - descriptionTA.setText(text) (下面类的最后一个方法),有时它设置正确,但大多数时候一切都停止,没有错误消息或其他生命信号。

这是出现问题的女巫的班级。

import animatedalgorithms.MasterFrame;
import animatedalgorithms.sorting.SortAnimationComponent;
import helperclasses.ApplicationConstants;
import helperclasses.RenderedJLabel;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.TreeMap;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.JTextArea;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import javax.swing.border.TitledBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;


public class SortAnimationPanel extends JPanel {

    private static final int DESCENDING_EELMENT_ORDER = 0;
    private static final int ASCENDING_ELEMEMENT_ORDER = 1;
    private static final int RANDOM_ELEMENT_ORDER = 2;

    private MasterFrame frame;
    private SortAnimationComponent comp;
    private RenderedJLabel h1;
    private JSlider algSlider;
    private JSlider animSlider;
    BackButtonComponent backBtn;
    private int elmOrder;
    private JTextArea descriptionTA ;


    public SortAnimationPanel(MasterFrame frame) {
        elmOrder = RANDOM_ELEMENT_ORDER;
        this.setBorder(new LineBorder(Color.black));
        this.frame = frame;
        this.setLayout(new BorderLayout());

        h1 = new RenderedJLabel("");
        h1.setFont(new Font("Segoe UI Semibold", Font.PLAIN, 20));
        h1.setForeground(Color.white);

        createControls();
    }

    public void createControls() {
        // Header
        JPanel header = new JPanel();
        header.setLayout(new BorderLayout());
        header.setBackground(new Color(30, 30, 30));
        header.setBorder(new EmptyBorder(0, 10, 5, 5));
        header.setForeground(Color.WHITE);
        header.add(h1, BorderLayout.CENTER);

        JPanel aboutBtn = new JPanel();
        aboutBtn.setName("aboutPanel");
        aboutBtn.setBackground(Color.BLACK);

        final RenderedJLabel aboutLabel = new RenderedJLabel("Apie algoritmą");
        aboutLabel.setForeground(Color.WHITE);
        aboutLabel.setFont(new Font("Arial", Font.BOLD, 12));
        aboutBtn.add(aboutLabel);

        header.add(aboutBtn, BorderLayout.EAST);
        add(header, BorderLayout.NORTH);        

        //Bottom controls
        JButton btn = new JButton("Iš naujo");
        btn.setName("replay");
        JButton btnPlay = new JButton("Rikiuoti");
        btnPlay.setName("play");
        JButton btnPause = new JButton("Pauzė");
        btnPause.setName("pause");
        JButton btnStep = new JButton("Žingsnis");
        btnStep.setName("step");
        backBtn = new BackButtonComponent();

        JPanel controls = new JPanel();
        controls.setLayout(new BoxLayout(controls, BoxLayout.X_AXIS));
        controls.setBackground(Color.WHITE);
        controls.add(btn);
        controls.add(btnPlay);
        controls.add(btnPause);
        controls.add(btnStep);
        controls.add(Box.createHorizontalStrut(10));

        Border empty = BorderFactory.createEmptyBorder(10, 10, 30, 10);
        controls.setBorder(empty);

        JPanel labels = new JPanel();
        labels.setLayout(new BoxLayout(labels, BoxLayout.Y_AXIS));
        labels.add(new JLabel("Algoritmo greitis: "));
        labels.add(new JLabel("Animacijos greitis: "));
        labels.setBackground(Color.WHITE);
        controls.add(labels);

        JPanel sliders = new JPanel();
        sliders.setBackground(Color.WHITE);
        sliders.setLayout(new BoxLayout(sliders, BoxLayout.Y_AXIS));
        algSlider = new JSlider(JSlider.HORIZONTAL, 100, 10000, 10000 - ApplicationConstants.DEFAULT_ALGORITHM_DELAY);
        algSlider.setBackground(Color.WHITE);
        algSlider.setMajorTickSpacing(2000);
        algSlider.setMinorTickSpacing(100);

        animSlider = new JSlider(JSlider.HORIZONTAL, 0, 20, 10);
        animSlider.setMajorTickSpacing(10);
        animSlider.setBackground(Color.WHITE);
        animSlider.setMinorTickSpacing(2);
        sliders.add(algSlider);
        sliders.add(animSlider);
        controls.add(Box.createHorizontalStrut(10));
        controls.add(sliders);

        class ButtonListener implements ActionListener {
            @Override
            public void actionPerformed(ActionEvent e) {
                JButton eventObj = (JButton)e.getSource();
                if (eventObj.getName().equalsIgnoreCase("play")) {
                    comp.setToPlay();
                } else if (eventObj.getName().equalsIgnoreCase("pause")) {
                    comp.setToPause();
                } else if (eventObj.getName().equalsIgnoreCase("replay")) {
                    resetControls();
                    switch (elmOrder) {
                    case RANDOM_ELEMENT_ORDER:
                        comp.generateRandomArray();
                        break;
                    case ASCENDING_ELEMEMENT_ORDER:
                        comp.generateAscendingArray();
                        break;
                    case DESCENDING_EELMENT_ORDER:
                        comp.generateDescendingArray();
                        break;
                    }
                    comp.resetSorter();
                    comp.startAnimation();
                } else if (eventObj.getName().equalsIgnoreCase("step")) {
                    comp.step();
                }
            }
        }

        class CustomMouseListener implements MouseListener {
            boolean pressed = false;

            @Override
            public void mouseClicked(MouseEvent e) {
            }

            @Override
            public void mousePressed(MouseEvent e) {
                pressed = true;
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                if (pressed) {
                    if (e.getSource() instanceof JPanel) {
                        JFrame aboutFrame = new DescriptionFrame(comp.getAlgorithmNum());
                    } else {
                        comp.stopThread();
                        frame.setVisibleCard(MasterFrame.MENU_WINDOW);
                    }
                }
            }

            @Override
            public void mouseEntered(MouseEvent e) {
                if (e.getSource() instanceof JPanel) {
                    JPanel p = (JPanel) e.getSource();
                    p.setBackground(Color.WHITE);
                    aboutLabel.setForeground(Color.black);
                } else {
                    BackButtonComponent comp = (BackButtonComponent)e.getSource();
                    comp.setCompColor(Color.lightGray);
                    comp.repaint();
                }
            }

            @Override
            public void mouseExited(MouseEvent e) {
                if (e.getSource() instanceof JPanel) {
                    JPanel p = (JPanel) e.getSource();
                    p.setBackground(Color.black);
                    aboutLabel.setForeground(Color.white);
                } else {
                    BackButtonComponent comp = (BackButtonComponent)e.getSource();
                    comp.setCompColor(Color.GRAY);
                    comp.repaint();
                    pressed = false;
                }
            }
        }


        class SliderListener implements ChangeListener {

            @Override
            public void stateChanged(ChangeEvent e) {
                JSlider source = (JSlider)e.getSource();
                if (!source.getValueIsAdjusting()) {
                    if (source.getMaximum() == 20) {
                        comp.setAnimationDelay(source.getMaximum() - source.getValue());
                    } else {
                        comp.setAlgorithmStepDelay(source.getMaximum() - source.getValue());
                    }
                }
            }
        }

        ActionListener btnListener = new ButtonListener();
        btn.addActionListener(btnListener);
        btnPlay.addActionListener(btnListener);
        btnStep.addActionListener(btnListener);
        btnPause.addActionListener(btnListener);

        CustomMouseListener l = new CustomMouseListener();
        backBtn.addMouseListener(l);
        aboutBtn.addMouseListener(l);        

        ChangeListener sliderListener = new SliderListener();
        algSlider.addChangeListener(sliderListener);
        animSlider.addChangeListener(sliderListener);

        add(controls, BorderLayout.SOUTH);

    }

    public void createLeftMenu() {

    }

    public void resetControls() {
        algSlider.setValue(algSlider.getMaximum() - ApplicationConstants.DEFAULT_ALGORITHM_DELAY);
        animSlider.setValue(animSlider.getMaximum() - ApplicationConstants.DEFAULT_ANIMATION_DELAY);
    }

    public void loadAlgorithm(int sorterNum) {
        resetControls();

        JPanel sortPanel = new JPanel();
        sortPanel.setBackground(Color.WHITE);

        descriptionTA = new JTextArea();
        descriptionTA.setSelectionColor(Color.BLACK);
        descriptionTA.setFocusable(false);
        descriptionTA.setEnabled(true);
        descriptionTA.setRows(5);
        descriptionTA.setColumns(10);
        descriptionTA.setFont(new Font("Arial", Font.BOLD, 12));
        descriptionTA.setWrapStyleWord(true);
        descriptionTA.setLineWrap(true);
        TitledBorder title = BorderFactory.createTitledBorder("Aprašymas");
        descriptionTA.setBorder(title);

        HistoryComponent hist = new HistoryComponent(new TreeMap<String, Color>(), 30);
        TreeMap<String, Color> map = new TreeMap<String, Color>();
        switch (sorterNum) {
            case ApplicationConstants.SELECTION_SORT_NUM:
            h1.setText("Išrinkimo rikiavimo algoritmas");
            map.put("- Mažiausias elementas", ApplicationConstants.IMPORTANT_ELEMENT_COLOR);
            map.put("- Pasirinktas elementas", ApplicationConstants.SELECTED_ELEMENT_COLOR);
            map.put("- Neutralus elementas", ApplicationConstants.NEUTRAL_ELEMENT_COLOR);
            map.put("- Surikiuotas masyvas", ApplicationConstants.SORTED_ELEMENT_COLOR);
            hist.setMap(map);
            hist.repaint();
            comp = new SortAnimationComponent(ApplicationConstants.SELECTION_SORT_NUM, this);
            comp.setToPause();
            comp.startAnimation();
            break;
            case ApplicationConstants.BUBBLE_SORT_NUM:
            h1.setText("Burbulo rikiavimo algoritmas");
            map.put("- Pasirinktas elementas", ApplicationConstants.SELECTED_ELEMENT_COLOR);
            map.put("- Neutralus elementas", ApplicationConstants.NEUTRAL_ELEMENT_COLOR);
            hist.setMap(map);
            hist.repaint();
            comp = new SortAnimationComponent(ApplicationConstants.BUBBLE_SORT_NUM, this);
            comp.setToPause();
            comp.startAnimation();
            break;
            case ApplicationConstants.INSERTION_SORT_NUM:
            h1.setText("Įterpimo rikiavimo algoritmas");
            map.put("- Surikiuotas masyvas", ApplicationConstants.SORTED_ELEMENT_COLOR);
            map.put("- Pasirinktas elementas", ApplicationConstants.SELECTED_ELEMENT_COLOR);
            map.put("- Neutralus elementas", ApplicationConstants.NEUTRAL_ELEMENT_COLOR);
            hist.setMap(map);
            hist.repaint();
            comp = new SortAnimationComponent(ApplicationConstants.INSERTION_SORT_NUM, this);
            comp.setToPause();
            comp.startAnimation();
            break;
            case ApplicationConstants.QUICK_SORT_NUM:
            h1.setText("Greitojo rikiavimo algoritmas");
            map.put("- Vidurio taškas ", ApplicationConstants.IMPORTANT_ELEMENT_COLOR);
            map.put("- Neutralus elementas", ApplicationConstants.NEUTRAL_ELEMENT_COLOR);
            map.put("- Neaktyvus elementas", ApplicationConstants.INACTIVE_ELEMENT_COLOR);
            hist.setMap(map);
            hist.repaint();
            comp = new SortAnimationComponent(ApplicationConstants.QUICK_SORT_NUM, this);
            comp.setToPause();
            comp.startAnimation();
            break;
            case ApplicationConstants.MERGE_SORT_NUM:
            h1.setText("Suliejimo rikiavimo algoritmas");
            map.put("- Neutralus elementas", ApplicationConstants.NEUTRAL_ELEMENT_COLOR);
            map.put("- Neaktyvus elementas", ApplicationConstants.INACTIVE_ELEMENT_COLOR);
            hist.setMap(map);
            hist.repaint();
            comp = new SortAnimationComponent(ApplicationConstants.MERGE_SORT_NUM, this);
            comp.setToPause();
            comp.startAnimation();
            break;
        default:
            h1.setText("Išrinkimo rikiavimo algoritmas");
            map.put("- Mažiausias elementas", ApplicationConstants.IMPORTANT_ELEMENT_COLOR);
            map.put("- Pasirinktas elementas", ApplicationConstants.SELECTED_ELEMENT_COLOR);
            map.put("- Neutralus elementas", ApplicationConstants.NEUTRAL_ELEMENT_COLOR);
            hist.setMap(map);
            hist.repaint();
            comp = new SortAnimationComponent(ApplicationConstants.SELECTION_SORT_NUM, this);
            comp.setToPause();
            comp.startAnimation();
            break;
        }

        JPanel leftPanel = new JPanel();
        leftPanel.setLayout(new BorderLayout());
        leftPanel.setBackground(Color.WHITE);
        JPanel spacer = new JPanel();
        spacer.setBackground(Color.white);
        spacer.setLayout(new BoxLayout(spacer, BoxLayout.X_AXIS));
        spacer.add(backBtn);
        spacer.add(Box.createHorizontalStrut(120));
        leftPanel.add(spacer, BorderLayout.NORTH);

        JPanel elmOrderPanel = new JPanel();
        elmOrderPanel.setLayout(new BoxLayout(elmOrderPanel, BoxLayout.Y_AXIS));
        elmOrderPanel.setBorder(BorderFactory.createTitledBorder("Elementų išdėstymas"));
        JButton ascBtn = new JButton("Didėjimo tvarka");
        ascBtn.setName("ascBtn");
        JButton descBtn = new JButton("Mažėjimo tvarka");
        descBtn.setName("descBtn");
        JButton randBtn = new JButton("Atsitiktine tvarka");
        randBtn.setName("randBtn");
        elmOrderPanel.add(ascBtn);
        elmOrderPanel.add(descBtn);
        elmOrderPanel.add(randBtn);
        elmOrderPanel.setBackground(Color.WHITE);
        leftPanel.add(elmOrderPanel, BorderLayout.SOUTH);

        TitledBorder colorBorder = BorderFactory.createTitledBorder("Spalvų reikšmės");
        hist.setBorder(colorBorder);
        leftPanel.add(hist, BorderLayout.CENTER);

        class ButtonListener implements ActionListener {
            @Override
            public void actionPerformed(ActionEvent e) {
                JButton eventObj = (JButton)e.getSource();
                if (eventObj.getName().equalsIgnoreCase("randBtn")) {
                    resetControls();
                    comp.generateRandomArray();
                    comp.resetSorter();
                    comp.startAnimation();
                    elmOrder = RANDOM_ELEMENT_ORDER;
                } else if (eventObj.getName().equalsIgnoreCase("descBtn")) {
                    resetControls();
                    comp.generateDescendingArray();
                    comp.resetSorter();
                    comp.startAnimation();
                    elmOrder = DESCENDING_EELMENT_ORDER;
                } else if (eventObj.getName().equalsIgnoreCase("ascBtn")) {
                    resetControls();
                    comp.generateAscendingArray();
                    comp.resetSorter();
                    comp.startAnimation();
                    elmOrder = ASCENDING_ELEMEMENT_ORDER;
                }
            }
        }
        ButtonListener l = new ButtonListener();
        ascBtn.addActionListener(l);
        descBtn.addActionListener(l);
        randBtn.addActionListener(l);

        sortPanel.setLayout(new BorderLayout());
        sortPanel.add(comp, BorderLayout.CENTER);
        sortPanel.add(descriptionTA, BorderLayout.SOUTH);
        sortPanel.add(leftPanel, BorderLayout.WEST);
        add(sortPanel, BorderLayout.CENTER);
        this.updateUI();
    }

    public void setDescriptionText(String text){        
        descriptionTA.setText(text);       
    }
}

setDescriptionText 从另一个线程调用,该线程管理 JtextArea 上方面板中的动画并在其中设置文本。

对我来说奇怪的是,它与 Java 7 之前的版本完美配合。

如果您需要更多代码来检测问题,请告诉我。

4

2 回答 2

2

您应该确保在 EventDispatchedThread 上调用 descriptionTA.setText() :

public void setDescriptionText(String text){      
    Runnable toEDT = new Runnable() {

        @Override
        public void run() {
            descriptionTA.setText(text);    
        }
    };

    if(SwingUtilities.isEventDispatchThread()) {
        toEDT.run();
    }else {
        SwingUtilities.invokeLater(toEDT);
    }
}

所有与 UI 相关的操作(实例化、修改等)都应该在 EDT 上,以避免死锁或其他有趣的事情。

于 2013-05-13T14:50:31.533 回答
2

Swing 有一个专门用于更新其 GUI 的线程。所以如果你想更新你的界面,不要调用任何其他线程,尝试使用保留方法更新你的界面:

SwingUtilities.invokeLater(new Runnable() {
    public void run() {
      // Here, we can safely update the GUI
      // because we'll be called from the
      // event dispatch thread
      statusLabel.setText("Query: " + queryNo);
    }
});
于 2013-05-13T15:04:30.623 回答