如何防止我的JFrame冻结?

时间:2014-01-11 18:39:12

标签: java multithreading jframe jbutton event-dispatch-thread

所以我的问题是有时当我在JFrame中按下JButtons时,整个框架冻结并且只能通过Eclipse终止它来退出。所有的JButton都有动作监听器,我不明白为什么它们有时会导致JFrame冻结而有时不会

感谢任何帮助。 这是我的代码:

//objects
static JFrame frame = new JFrame("Flash cards revision");
static JButton beginButton = new JButton();
static JButton continueButton = new JButton("CONTINUE");
static JButton def1Button;
static JButton def2Button;
static JButton def3Button;
static JLabel keywordLabel = new JLabel();
static JLabel title = new JLabel("BIOLOGY FLASH CARDS");
static JLabel completionCount = new JLabel("Number of keywords completed - 0/15");
static JLabel message = new JLabel();

//variables
static Color backgroundColor = new Color(255, 204, 0);
static Color labelColor = new Color(44, 103, 0);
static Color buttonColor = new Color(146, 205, 0);
static Color highlightedButtonColor = new Color(255, 105, 0);
static Font textFont = new Font("Myriad Pro", Font.PLAIN, 15);
static Border border = BorderFactory.createLineBorder(Color.BLACK);
static String[] keywordsArray = new String[15];
static String[] definitionsArray = new String[15];
static boolean[] beenUsed = new boolean[15];
static int rDefNum;
static int rButtonNum;
static int rWDefNum;
static int numTimesCorrect = 0;
static int numComplete = 0;
static int originalY = 0;
static String keyword;
static String definition;
static String wDef1;
static String wDef2;

public static void main(String[] args) throws IOException
{
    prepareFrame();
    occupyKeywordsArray();
    occupyDefinitionsArray();
    prepareMenu();

    beginButton.addActionListener(new ActionListener()
    {
        public void actionPerformed(ActionEvent e)
        {
            beginButton.removeActionListener(beginButton.getActionListeners()[0]);
            prepareTest();
            getNewKeyword();
            getWrongDefinitions();
            prepareNewDefinition();
            addActionListeners();
        }
    });
}
static void prepareFrame()
{
    frame.setVisible(true);
    frame.setResizable(false);
    frame.setLayout(null);
    frame.setSize(800,600);
    frame.setLocation(500,200);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().setBackground(backgroundColor);
    frame.setIconImage(Toolkit.getDefaultToolkit().getImage("biologyIcon.png"));

}
static void prepareMenu()
{
    beginButton = new JButton("BEGIN TEST");
    frame.add(title);
    frame.add(beginButton);

    title.setOpaque(true);
    title.setSize(650,100);
    title.setLocation(75,60);
    title.setHorizontalAlignment(SwingConstants.CENTER);
    title.setBackground(labelColor);
    title.setForeground(buttonColor);
    title.setFont(textFont);
    title.setFont(title.getFont().deriveFont(60.0f));
    title.setBorder(border);

    beginButton.setBackground(buttonColor);
    beginButton.setLocation(240,220);
    beginButton.setForeground(labelColor);
    beginButton.setFont(textFont);
    beginButton.setFont(beginButton.getFont().deriveFont(55.0f));
    beginButton.setSize(320,100);
    beginButton.setFocusable(false);
    beginButton.setBorder(border);
}
static void prepareTest()
{
    def1Button = new JButton();
    def2Button = new JButton();
    def3Button = new JButton();
    continueButton = new JButton("CONTINUE");

    frame.remove(title);
    frame.remove(beginButton);
    frame.add(keywordLabel);
    frame.add(message);
    frame.add(completionCount);
    frame.add(def1Button);
    frame.add(def2Button);
    frame.add(def3Button);
    frame.add(continueButton);

    frame.repaint();
    frame.revalidate();

    keywordLabel.setOpaque(true);
    keywordLabel.setHorizontalAlignment(SwingConstants.CENTER);
    keywordLabel.setBackground(labelColor);
    keywordLabel.setForeground(buttonColor);
    keywordLabel.setFont(textFont);
    keywordLabel.setFont(keywordLabel.getFont().deriveFont(60.0f));
    keywordLabel.setBorder(border);

    message.setOpaque(true);
    message.setText("Try to match the keyword to the correct definition");
    message.setSize(450,35);
    message.setLocation(175,370);
    message.setHorizontalAlignment(SwingConstants.CENTER);
    message.setBackground(labelColor);
    message.setForeground(buttonColor);
    message.setFont(textFont);
    message.setFont(keywordLabel.getFont().deriveFont(20.0f));
    message.setBorder(border);

    completionCount.setOpaque(true);
    completionCount.setSize(340,35);
    completionCount.setLocation(230,20);
    completionCount.setHorizontalAlignment(SwingConstants.CENTER);
    completionCount.setBackground(labelColor);
    completionCount.setForeground(buttonColor);
    completionCount.setFont(textFont);
    completionCount.setFont(keywordLabel.getFont().deriveFont(20.0f));
    completionCount.setBorder(border);

    continueButton.setVisible(false);
    continueButton.setSize(300,100);
    continueButton.setLocation(250,370);
    continueButton.setBackground(buttonColor);
    continueButton.setForeground(labelColor);
    continueButton.setFont(textFont);
    continueButton.setFont(def1Button.getFont().deriveFont(50.0f));
    continueButton.setFocusable(false);
    continueButton.setBorder(border);

    def1Button.setBackground(buttonColor);
    def1Button.setForeground(labelColor);
    def1Button.setFont(textFont);
    def1Button.setFont(def1Button.getFont().deriveFont(20.0f));
    def1Button.setFocusable(false);
    def1Button.setBorder(border);

    def2Button.setBackground(buttonColor);
    def2Button.setForeground(labelColor);
    def2Button.setFont(textFont);
    def2Button.setFont(def2Button.getFont().deriveFont(20.0f));
    def2Button.setFocusable(false);
    def2Button.setBorder(border);

    def3Button.setBackground(buttonColor);
    def3Button.setForeground(labelColor);
    def3Button.setFont(textFont);
    def3Button.setFont(def3Button.getFont().deriveFont(20.0f));
    def3Button.setFocusable(false);
    def3Button.setBorder(border);
}
static void prepareNewDefinition()
{
    rButtonNum = r.nextInt(3)+1;//Chooses a random number - 1, 2 or 3

    switch(rButtonNum)
    {
    case 1:
        def1Button.setText(definition);
        def2Button.setText(wDef1);
        def3Button.setText(wDef2);
        break;
    case 2:
        def1Button.setText(wDef1);
        def2Button.setText(definition);
        def3Button.setText(wDef2);
        break;
    case 3:
        def1Button.setText(wDef1);
        def2Button.setText(wDef2);
        def3Button.setText(definition);
        break;
    }

    int b1Width = def1Button.getFontMetrics(def1Button.getFont()).stringWidth(def1Button.getText()) + 45;
    int b2Width = def2Button.getFontMetrics(def2Button.getFont()).stringWidth(def2Button.getText()) + 45;
    int b3Width = def3Button.getFontMetrics(def3Button.getFont()).stringWidth(def3Button.getText()) + 45;

    keywordLabel.setText(keyword);
    keywordLabel.setSize(keyword.length()*40,100);
    keywordLabel.setLocation(400-((keyword.length()*40)/2),80);

    def1Button.setSize(b1Width,30);
    def1Button.setLocation(400 - def1Button.getWidth() / 2,210);

    def2Button.setSize(b2Width,30);
    def2Button.setLocation(400 - def2Button.getWidth() / 2,260);

    def3Button.setSize(b3Width,30);
    def3Button.setLocation(400- def3Button.getWidth() / 2,310);

    optionsListener = new ActionListener()
    {
        public void actionPerformed(ActionEvent e)
        {
            def1Button.removeActionListener(optionsListener);
            def2Button.removeActionListener(optionsListener);
            def3Button.removeActionListener(optionsListener);
            if(e.getActionCommand().equals(definition))
            {
                correct();
            }
            else
            {
                incorrect();
            }
        }
    };
}
static void correct()
{
    numTimesCorrect++;
    if(numTimesCorrect == 1)
    {
        message.setText("Correct! Match this correctly once more to complete this keyword");
        message.setSize(550,35);
        message.setLocation(125,message.getY());
    }
    else
    {
        numComplete++;
        completionCount.setText("Number of keywords completed - "+numComplete+"/15");
        message.setText("Correct! Keyword complete!");
        message.setSize(250,35);
        message.setLocation(275,message.getY());
    }
    moveMessageDown();
    continueButton.addActionListener(new ActionListener()
    {
        public void actionPerformed(ActionEvent e)
        {
            System.out.println(continueButton.getActionListeners()[0]);
            continueButton.setVisible(false);
            continueButton.removeActionListener(continueButton.getActionListeners()[0]);
            if(numTimesCorrect == 1)
            {
                message.setSize(510,35);
                message.setLocation(145,message.getY());
                message.setText("Match this correctly once more to complete this keyword");
            }
            if(numTimesCorrect == 2)
            {
                message.setSize(450,35);
                message.setLocation(175,message.getY());
                message.setText("Try to match the keyword to the correct definition");
                getNewKeyword();
                numTimesCorrect = 0;
            }
            getWrongDefinitions();
            prepareNewDefinition();
            addActionListeners();
            moveMessageUp();
        }
    });
}
static void incorrect()
{
    numTimesCorrect = 0;
    message.setText("Incorrect! The correct definition is now highlighted");
    message.setForeground(highlightedButtonColor);

    if(def1Button.getText().equals(definition))
    {
        def1Button.setBackground(highlightedButtonColor);
    }
    if(def2Button.getText().equals(definition))
    {
        def2Button.setBackground(highlightedButtonColor);
    }
    if(def3Button.getText().equals(definition))
    {
        def3Button.setBackground(highlightedButtonColor);
    }
    message.setSize(450,35);
    message.setLocation(175,message.getY());
    moveMessageDown();

    continueButton.addActionListener(new ActionListener()
    {
        public void actionPerformed(ActionEvent e)
        {
            continueButton.setVisible(false);
            continueButton.removeActionListener(continueButton.getActionListeners()[0]);
            message.setForeground(buttonColor);
            getWrongDefinitions();
            prepareNewDefinition();
            def1Button.setBackground(buttonColor);
            def2Button.setBackground(buttonColor);
            def3Button.setBackground(buttonColor);
            message.setLocation(175,500);
            message.setText("Try to match the keyword to the correct definition");
            addActionListeners();
            moveMessageUp();
        }
    });
}
static void getNewKeyword() 
{
    boolean validDef = false;

    while(validDef == false)
    {
        rDefNum = r.nextInt(15);
        if(beenUsed[rDefNum] == false)
        {
            validDef = true;
            beenUsed[rDefNum] = true;
            keyword = keywordsArray[rDefNum];
            definition = definitionsArray[rDefNum];
        }
    }
}
static void getWrongDefinitions() 
{
    rWDefNum = r.nextInt(15);
    wDef1 = definitionsArray[rWDefNum]; 
    rWDefNum = r.nextInt(15);
    wDef2 = definitionsArray[rWDefNum]; 
    while(wDef1.equals(wDef2) || definition.equals(wDef1) || definition.equals(wDef2))
    {
        rWDefNum = r.nextInt(15);
        wDef1 = definitionsArray[rWDefNum]; 
        wDef2 = definitionsArray[rWDefNum]; 
    }
}
static void moveMessageDown()
{
    moveUpThread.stop();
    originalY = message.getY();
    moveDownThread = new Thread()
    {
        public void run()
        {
            try 
            {
                Thread.sleep(200);
            }catch (InterruptedException e){}

            for(int loop = 0; loop <= 500-originalY; loop++)
            {
                try 
                {
                    Thread.sleep(6);
                } catch (InterruptedException e){}

                message.setLocation(message.getX(),originalY+loop);
            }
            continueButton.setVisible(true);
        }
    };
    moveDownThread.start();
}
static void moveMessageUp()
{
    originalY = message.getY();
    moveUpThread = new Thread()
    {
        public void run()
        {

            try 
            {
                Thread.sleep(200);
            }catch (InterruptedException e){}

            for(int loop = 0; loop <= 630 - originalY; loop++)
            {
                try 
                {
                    Thread.sleep(6);
                } catch (InterruptedException e){}

                message.setLocation(message.getX(),500-loop);
            }
        }
    };
    moveUpThread.start();
}
static void addActionListeners()
{
    def1Button.addActionListener(optionsListener);
    def2Button.addActionListener(optionsListener);
    def3Button.addActionListener(optionsListener);
}
static void occupyKeywordsArray() throws IOException 
{
    BufferedReader keywordsReader = new BufferedReader(new FileReader("keywords.txt"));
    for(int keywordsLoop = 0; keywordsLoop <= 14; keywordsLoop++)
    {
        keywordsArray[keywordsLoop] = keywordsReader.readLine();
        keywordsReader.readLine();
    }
    keywordsReader.close();
}
static void occupyDefinitionsArray() throws IOException 
{
    BufferedReader definitionsReader = new BufferedReader(new FileReader("keywords.txt"));
    for(int definitionsLoop = 0; definitionsLoop <= 14; definitionsLoop++)
    {
        definitionsReader.readLine();
        definitionsArray[definitionsLoop] = definitionsReader.readLine();
    }
    definitionsReader.close();
}
 }

2 个答案:

答案 0 :(得分:2)

您必须在侦听器中创建一个线程。像这样:

button.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {

                Thread hilo = new Thread(new Runnable() {

                    @Override
                    public void run() {

                        //here your code

                    }
                });         
                hilo.start();

            }
        });

如果JFrame没有冻结只是因为执行速度很快而且没有时间冻结,但如果执行需要的时间超过几秒钟,那么JFrame将会冻结。

答案 1 :(得分:0)

我和@carexcer一样使用invokeLater调用,如下所示,它对我有用:

public static void main(String[] args) {
//        EventQueue.invokeLater(() -> {
        Toolkit.getDefaultToolkit().setDynamicLayout(false);
        final JFrame frame = new JFrame();
        frame.setUndecorated(true);
        final JToggleButton backgroundButton = new JToggleButton("Break me!");
        backgroundButton.setSelected(true);
        backgroundButton.addActionListener(e -> {
            if(!backgroundButton.isSelected()) {
                EventQueue.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        frame.setBackground(new Color(0, 0, 0, 0));
                        backgroundButton.setText("Fix me!");
                    }
                });
            } else {
                EventQueue.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        frame.setBackground(UIManager.getColor("control"));
                        backgroundButton.setText("Break me!");
                    }
                });                 
            }
        });
        final JLabel label = new JLabel("Resize Here");
        label.setBorder(BorderFactory.createLineBorder(Color.RED));
        frame.getContentPane().add(backgroundButton);
        frame.getContentPane().add(label, BorderLayout.SOUTH);
        new ComponentResizer(frame);

        frame.pack();
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setVisible(true);
//       });
}