الحصول على ENTER للعمل مع JSpinner بالطريقة التي يعمل بها مع JTextField

StackOverflow https://stackoverflow.com/questions/379675

سؤال

أولاً، لكي أجعل شرح عملي أسهل قليلًا، إليك بعضًا من الكود الخاص بي:

JSpinner spin = new JSpinner();
JFormattedTextField text = getTextField(spin);

text.addActionListener(new java.awt.event.ActionListener() {
    public void actionPerformed(java.awt.event.ActionEvent evt) {
            // Do stuff...
    }
});

...

private JFormattedTextField getTextField(JSpinner spinner) {
    JComponent editor = spinner.getEditor();

    if (editor instanceof JSpinner.DefaultEditor) {
        return ((JSpinner.DefaultEditor )editor).getTextField();
    } else {
        System.err.println( "Unexpected editor type: "
                           + spinner.getEditor().getClass()
                           + " isn't a descendant of DefaultEditor" );
        return null;
    }
}

وكما ترون، لقد وصلت إلى هذا الحد.وبالفعل، عندما أكتب قيمة في مكون حقل النص في القرص الدوار (JFormattedTextField)، ثم اضغط على ENTER، وهو يعمل.

ما أريده الآن هو أن أكون قادرًا على جعل حقل النص يستجيب لـ ENTER دون الحاجة إلى كتابة قيمة جديدة يدويًا (وهو ما يتعارض نوعًا ما مع الغرض من إخراج الدوار منه).كيف يمكنني فعل ذلك؟

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

المحلول

وأنا أعلم أن هذا ليس هو المستمع العمل ... ولكن ربما يمكن لهذا العمل بالنسبة لك؟


    text.addKeyListener( new KeyAdapter() {
            @Override
            public void keyReleased( final KeyEvent e ) {
                if ( e.getKeyCode() == KeyEvent.VK_ENTER ) {
                    System.out.println( "enter pressed" );
                }
            }
        } );

نصائح أخرى

لقد واجهت للتو مشكلة تتعلق بهذا بنفسي.في حالتي، كان لدي JSpinner مع SpinnerNumberModel الإعداد حتى أتمكن من إدخال قيم المعرفات الرقمية، ثم استردادها من قاعدة بيانات بعيدة.لقد نجح هذا بشكل جيد مع JButton كمشغل للاستعلام، ولكنني أردت أن أكون قادرًا على تحويل التركيز إلى الحقل عبر علامة التبويب، والضغط على زر الإدخال، وأن أكون قادرًا أيضًا على تغيير القيمة عن طريق إدخال معرف باستخدام مفاتيح رقمية ، ثم اضغط على زر الإدخال.

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

((JSpinner.DefaultEditor) minRng.getEditor()).getTextField().addKeyListener(new KeyAdapter() {
    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
            queryData();
        }
    }
});

و طريقة الاستعلام :

private void queryData() {
    int minVal = Integer.parseInt(minRng.getValue().toString());
    queryDataBase(minVal);
}

لإصلاح هذه المشكلة، كل ما كان علي فعله هو إجبار الاستعلام على الانتظار حتى يتم تشغيله حتى يقوم القرص الدوار بتحديث قيمته، وهو ما تم القيام به بسهولة باستخدام SwingUtilities.invokeLater() لإجباره على الوصول إلى نهاية قائمة انتظار EDT، كما يلي:

((JSpinner.DefaultEditor) minRng.getEditor()).getTextField().addKeyListener(new KeyAdapter() {
    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == KeyEvent.VK_ENTER) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    queryData();
                }
            });
        }
    }
});

شكرا ل invokeLater() يحدث الاستعلام الآن على القيمة الجديدة بدلاً من القيمة السابقة، عند الضغط على زر الإدخال، حيث قام JSpinner بعد ذلك بتحديث قيمته إلى القيمة المدخلة حديثًا.

أفترض أن السبب في ذلك هو أن القيمة التي تم إدخالها لا يتم تطبيقها رسميًا على JSpinner حتى تضغط على زر الإدخال، والذي يؤدي أيضًا إلى تشغيل أداة الاستماع الرئيسية للاستعلام.ال KeyEvent لأن مستمع المفتاح المخصص [الاستعلام] يبدو أنه الأول في قائمة الانتظار، لذلك يقوم بتشغيل الكود الخاص به أولاً، ثم KeyEvent لتطبيق القيمة على JSpinner من الداخل JFormattedTextField, ، ولهذا السبب يستعلم عن القيمة القديمة. SwingUtilities.invokeLater() فقط يضع الاستعلام نفسه في نهاية قائمة الانتظار، لذلك يسمح للآخر KeyEvent لإنهاء التعليمات البرمجية الخاصة به قبل تشغيل الاستعلام.

يحرر:

هناك طريقة أخرى لتحقيق ذلك وهي طلب القيمة مباشرةً من ملف JFormattedTextField بدلا من JSpinner, ، حيث يجب أن يؤدي ذلك أيضًا إلى إرجاع القيمة التي تم إدخالها حديثًا منذ JFormattedTextField يحتوي على القيمة التي كتبتها، ولكن لم يتم تمريرها بعد إلى JSpinner، والذي يبدو أنه المكان الذي تكمن فيه المشكلة.

private void queryData() {
    JFormattedTextField tf = ((JSpinner.DefaultEditor) minRng.getEditor()).getTextField();
    int minVal = Integer.parseInt(tf.getText());
    queryDataBase(minVal);
}

المشكلة الوحيدة في هذه الطريقة هي أنه سيتعين عليك بعد ذلك التقاط أي منها NumberFormatExceptions، عند تحليل القيمة، حيث SwingUtilities.invokeLater() يسمح الأسلوب للنموذج الدوار بإزالة أي أحرف غير صالحة تلقائيًا ومتابعة الاستعلام.

على أي حال، ما زلت عديم الخبرة إلى حد ما في لغة Java، لذا إذا كان فهمي لهذا غير صحيح، فيرجى إبلاغي بذلك في التعليقات.

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