سؤال

أنا أصنع مشروعًا وأحتاج إلى شريط تقدم. لقد حصلت على الفصل مع الموقت وهو يعمل بشكل جيد عندما أقوم بتضمين رئيسي ؛ ولكن عندما أحاول أن أسميها في طريقة Maingui ، يكون كل شيء أسود حتى يصل إلى 100 ٪ ثم يظهر.

package microproject.resources;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

public class Timer extends JFrame {

    JProgressBar current;
    JTextArea out;
    JButton find;
    Thread runner;
    int num = 0;
    int length = 0;

    public Timer() {
        setTitle("Progress");
        setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        length = Integer.parseInt(JOptionPane.showInputDialog(null, "How many seconds:"));

        JPanel p = new JPanel(new GridLayout(1,1));
        p.setPreferredSize(new Dimension(300,65));
        current = new JProgressBar(0, length);
        current.setPreferredSize(new Dimension(250,50));
        current.setValue(0);
        current.setStringPainted(true);
        p.add(current);
        setVisible(true);
        setContentPane(p);
        pack();
        setVisible(true);
        iterate();
    }

    public void iterate() {
        while(num < length +1) {
            current.setValue(num);
            try {
                Thread.sleep(1000);
            } catch(InterruptedException e) {}
            num += 1;
        }

    }

    public static void main(String[] args) {
        Timer f = new Timer();
    }
}

هذا هو رمز فئة المؤقت ^

package microproject.resources;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

public class GUIMain extends JFrame {

    public static void main(String []args){            
        GuiFrame();        
    }    

    public static void GuiFrame(){
        JFrame frame = new JFrame("Casino Royal3");
        frame.setSize(811,577);
        frame.setDefaultCloseOperation(EXIT_ON_CLOSE);

        frame.setLayout(new GridLayout(2,1));
        frame.setResizable(false);
        JPanel PNorth = new JPanel(new FlowLayout(FlowLayout.LEFT,0,0));
        JPanel PSouth = new JPanel(new BorderLayout());


        //Creating Image for Casino Button
        ImageIcon img1 = new ImageIcon("src\\Casino.jpg");
        final JButton btn1 = new JButton(img1);
        btn1.setPreferredSize(new Dimension(550,274));
        btn1.setMargin(new Insets(0,0,0,0));
        PNorth.add(btn1, BorderLayout.EAST);
        btn1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                btn1.setIcon(new ImageIcon("src\\Casino2.jpg"));
            }
        });

        //Creating Image for Sheridan Label
        ImageIcon img2 = new ImageIcon("src\\SHERIDAN_LOGO.jpg");
        JButton btn2 = new JButton(img2);
        btn2.setMargin(new Insets(0,0,0,0));
        PNorth.add(btn2);
        btn2.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                ImageIcon instruc = new ImageIcon("src\\Instructions.jpg");
                JLabel instructions = new JLabel(instruc);
                JOptionPane.showConfirmDialog(null, instructions, "instructions", JOptionPane.DEFAULT_OPTION, JOptionPane.PLAIN_MESSAGE);
            }
        });

        JPanel timmus = new JPanel(new FlowLayout(FlowLayout.LEFT,0,0));
        timmus.setPreferredSize(new Dimension(166, 273));
        timmus.setBackground(Color.BLUE);

        ImageIcon time = new ImageIcon("src\\Timer.jpg");
        JButton timer = new JButton(time);
        timer.setMargin(new Insets(0,0,0,0));
        timer.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Timer f = new Timer();
            }
        });
        timmus.add(timer);

        ImageIcon mus = new ImageIcon("src\\music.jpg");
        JButton music = new JButton(mus);
        music.setMargin(new Insets(0,0,0,0));
        timmus.add(music);

        JPanel games = new JPanel(new FlowLayout(FlowLayout.LEFT,0,0));
        games.setPreferredSize(new Dimension(500,279));
        games.setBackground(Color.BLUE);

        ImageIcon calculator = new ImageIcon("src\\Calculator.jpg");
        JButton calc = new JButton(calculator);
        calc.setMargin(new Insets(0,0,0,0));
        calc.setPreferredSize(new Dimension(166,273));
        games.add(calc);
        calc.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Calculator c1 = new Calculator();
            }
        });

        ImageIcon g1 = new ImageIcon("src\\250Hangman.jpg");
        JButton game1 = new JButton(g1);
        //game1.setBackground(Color.WHITE);
        game1.setMargin(new Insets(0,0,0,0));
        game1.setPreferredSize(new Dimension(166,273));
        games.add(game1);
        game1.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                Hangman h1 = new Hangman();
            }
        });


        ImageIcon g2 = new ImageIcon("src\\Minesweeper.jpg");
        JButton game2 = new JButton(g2);
    //    game2.setBackground(Color.WHITE);
        game2.setMargin(new Insets(0,0,0,0));    
        game2.setPreferredSize(new Dimension(166,273));
        games.add(game2);

        PSouth.add(timmus, BorderLayout.CENTER);
        PSouth.add(games, BorderLayout.EAST);

        frame.add(PNorth, BorderLayout.NORTH);
        frame.add(PSouth, BorderLayout.SOUTH);

        frame.setVisible(true);
        frame.pack();
    }
}

هذا هو البرنامج بأكمله ، يطلق على جهاز التوقيت "Timer"

شكرا مقدما

هل كانت مفيدة؟

المحلول

مرحبًا بكم في عالم الإرسال الأحداث المحظور الرائع (وانتهاك الخيط الأولي)

في الأساس ، يعد Swing بيئة واحدة ملولبة ، ومن المتوقع أن يتم تنفيذ جميع التحديثات والتعديلات على واجهة المستخدم في سياق مؤشر ترابط إرسال الحدث (AKA EDT).

يعد EDT مسؤولاً ، من بين أشياء أخرى ، معالجة طلبات إعادة الطلاء. إذا قمت ، لسبب ما ، بمنع هذا الموضوع (على سبيل المثال ، باستخدام حلقة طويلة المدى أو حظر IO) ، فسيمنع ذلك EDT من معالجة طلبات الطلاء الجديدة ، مما يجعله يبدو كما لو أن برنامجك قد علق ... لأنه بشكل أساسي لديها.

سبب رؤية الفرق بين الجري Timer مباشرة واستخدامه في واجهة المستخدم الرسومية الخاص بك هو أنه عند بدء التطبيق ، سيتم تشغيله في الداخل ، وما يُعرف باسم الخيط "الرئيسي".

عندما تقوم أولاً بإنشاء حاوية أرجوحة ذات مستوى أعلى ، يتم تشغيل EDT (وهو مؤشر ترابط منفصل) ، مما يعني أن واجهة المستخدم ستظهر في خيطها الخاص ، لكن التطبيق سيستمر في تشغيل الخيط "الرئيسي" ، مما يسمح لك iterate طريقة لتشغيل بشكل مستقل عن EDT.

ومع ذلك ، عندما تحاول تشغيله من داخل واجهة المستخدم الرسومية ، فإن كل شيء يعمل في سياق EDT ، مما تسبب في حظره.

ابدأ بإلقاء نظرة على

لإصلاح المشكلة ، بناءً على رمز المثال الخاص بك ، أود أن أقترح استخدام أ SwingWorker. سيسمح لك ذلك بتشغيل "مهمتك الطويلة" في موضوع خلفية ، ولكنها توفر عددًا من الطرق التي تتيح لك إعادة مزامنة التحديثات الخاصة بك مرة أخرى إلى EDT. هذا مهم للغاية ، حيث يجب ألا تحاول أبدًا تحديث واجهة المستخدم أو تغيير حالتها من أي موضوع آخر ثم EDT.

ألق نظرة على خيوط العمال ورجال الأرجوحة لمزيد من التفاصيل

وإذا لزم الأمر ، بعض الأمثلة ...

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top