الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

تحديد لغة الإدخال الإفتراضية في ال Swing

بدأه san3aniJava في 15 مايو 2010 · 8 رد · 1,331 مشاهدة · في JavaSE
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

بسم الله الرحمن الرحيم

أتمنى أن عنوان موضوعي مناسب وموافق لقوانين الموقع وشروطه واعتذر مقدماً إن كان غير ذلك

سؤالي للاساتذة الافاضل عن إمكانية تحديد لغة الإدخال الافتراضية في Swing Text Components

فالملاحظ أنه عند تشغيل برنامج الجافا اللغة الافتراضية للادخال هي الانجليزي

فعند الشروع في الكتابة في TextField أو TextArea أو غيرها تكون اللغة الافتراضية الانجليزية ويحتاج المستخدم إلى تغيير لغة النظام إلى العربية دائماً وهذا قد يسبب ازعاج للمستخدم أنه كل ما أراد تشيل البرنامج يحتاج يغير اللغة

أتوقع أن هذا الأمر يتعلق بالنظام أكثر من الجافا لكن هل واجهتم هذه المشكلة من قبل وهل من حلول ولو ملتوية لهذه المشكلة ؟

أشكركم جيمعا مقدما

تحياتي

لا بد من صنعاء وان طال السفر

#2

بكل أمانة هذه المشكلة أثقلت كاهلي منذ سنين

ولم أجد لها أي حل

أفضل حلول وجدتها هو أن تقوم بفحص الحرف الذي يكتبه المستخدم في أول مرة

لكن المشكلة أن البرنامج لن يأخذ أول حرف يدخله المستخدم

الحل الثاني ضغظ زري shift+alt برمجياً

لكن المشكلة أنك لا تضمن إذا كان المستخدم يكتب فعلياً بالعربي

(جافا تأخذ اللغة الافتراضية من نظام التشغيل)

المشكلة أني لم أستطع معرفة اللغة الافتراضية لنظام التشغيل من جافا

تحياتي

حزمة المحرك الإصدارة 0.8

أي أحد يجد أني ظلمته فليراسلني

وبإذن الله لو كان له حق سيأخذه

728x90.png

#3
علاء الصالحي كتب:

بكل أمانة هذه المشكلة أثقلت كاهلي منذ سنين

ولم أجد لها أي حل

أفضل حلول وجدتها هو أن تقوم بفحص الحرف الذي يكتبه المستخدم في أول مرة

لكن المشكلة أن البرنامج لن يأخذ أول حرف يدخله المستخدم

الحل الثاني ضغظ زري shift+alt برمجياً

لكن المشكلة أنك لا تضمن إذا كان المستخدم يكتب فعلياً بالعربي

(جافا تأخذ اللغة الافتراضية من نظام التشغيل)

المشكلة أني لم أستطع معرفة اللغة الافتراضية لنظام التشغيل من جافا

تحياتي

بالفعل استاذي علاء هي مشكلة عويصة

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

والحلين الذين ذكرتهما استاذي كما لا يخفى عليك لا يلبيا الحاجة ومشاكلهما جوهرية

والحل الوحيد العملي الذي استخدمه منذ زمن مع كونه مزعج جدا لكن يبدوا أنه الوحيد الخالي من المشاكل هو

في الجافا نفسها عمل ComboBox أو خيار لتحديد لغة الأدخال ثم حسب اللغة المحددة تتبع الـ KeyEvent الصادرة من ضغط زر الكيببورد وتحويل الحرف أو الرمز الناتج إلى اليونوكود المقابل حسب اللغة المختارة

بهذا تكون الجافا متحررة تماما من رحمة النظام الذي تعمل عليه

لكن هذا الحل متعب ويحتاج إلى جهد كبير إذا ما كانت عدد لغات الإدخال التي تريد دعمها كثيرة

لكن ما زلت أحس أن هنالك حل لا نعرفه أسهل من هذه الحلول فمن غير المنطقي أن تخفى مثل هذه المسألة البديهية عن شركة Sun المصممة للجافا

بالمناسبة استاذي علاء هل عندك علم بوجود API خارجي للجافا لغرض الاتصال بالويندوز على الأقل لمعرفة ما هي لغات الإدخال المدعومة واختيار أحدها

ختاماً أشكر لك حضورك وجوابك القيم المفيد

وجزاكم الله خير

تلميذكم san3aniJava

دمج

لا بد من صنعاء وان طال السفر

#4

جرب هذه الشفرة

    // ex. setLanguage("ar", this);
    public static void setLanguage(String lang, JFrame frame){
    	if(lang!=null && !lang.trim().equals("") && frame!=null){
			Locale[] locales = Locale.getAvailableLocales();
			for(int i=0; i<locales.length;i++){
				java.util.Locale locale = locales;
		         if(locale.getLanguage().equals(lang)){
		        	 frame.getInputContext().selectInputMethod(locale);
		         }
		    }
    	}
	}
#5

هذا مثال مع اضافة تحسين للكود السابق

في الكود السابق يكون التغيير على مستوى JFrame

وفي الكود التالي لديك خياران اما ان تقوم بتغيير اللغة JFrame بالكامل باستخدام الامر التالي

setLanguage("ar", null, this);

او يتم التغيير على مستوى الحقل ، حيث يكون هناك حقول باللغة العربية و حقول اخرى باللغة الانجليزية، باستخدام الكود التالي

focusListener("ar", ComponentOrientation.RIGHT_TO_LEFT, fNameAField, lNameAField);
        focusListener("en", ComponentOrientation.LEFT_TO_RIGHT, fNameEField, lNameEField);

package test.language;

import java.awt.Component;
import java.awt.ComponentOrientation;
import java.awt.GridLayout;
import java.util.Locale;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;


/**
 * @author othman
 *
 */
public class TestFrame extends javax.swing.JFrame {

	private static final long serialVersionUID = 1L;



	public TestFrame() {
		setLayout(new GridLayout(1,2, 100, 50));
		setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        initComponents();

    }

    private void initComponents() {

    	JPanel enPanel=new JPanel(new GridLayout(2,2));
        JLabel fNameELabel=new JLabel("f-name");
        JLabel lNameELabel=new JLabel("l-name");
        JTextField fNameEField=new JTextField(20);
        JTextField lNameEField=new JTextField(20);
        enPanel.add(fNameELabel);
        enPanel.add(fNameEField);
        enPanel.add(lNameELabel);
        enPanel.add(lNameEField);

    	JPanel arPanel=new JPanel(new GridLayout(2,2));
    	JLabel fNameALabel=new JLabel("الاسم الاول");
        JLabel lNameALabel=new JLabel("الاسم الثاني");
        JTextField fNameAField=new JTextField(20);
        JTextField lNameAField=new JTextField(20);

        arPanel.add(fNameAField);
        arPanel.add(fNameALabel);
        arPanel.add(lNameAField);
        arPanel.add(lNameALabel);

        this.add(enPanel);
        this.add(arPanel);

//      هنا سيتم تحويل اللغة الى العربية عند انشاء الفورم
//    	setLanguage("ar", null, this);  

//        هنا يكون التحويل عند الدخول الى احد الحقول
        focusListener("ar", ComponentOrientation.RIGHT_TO_LEFT, fNameAField, lNameAField);
        focusListener("en", ComponentOrientation.LEFT_TO_RIGHT, fNameEField, lNameEField);

    	pack();
    	setLocationRelativeTo(null);



    }

    public static void focusListener(final String lang, final ComponentOrientation  componentOrientation, Component... components){
    	for(final Component component:components){
        	component.addFocusListener(new java.awt.event.FocusAdapter() {
                public void focusGained(java.awt.event.FocusEvent evt) {
                	setLanguage(lang,  componentOrientation, component);
                }
            });
    	}
    }


    public static void setLanguage(String lang, ComponentOrientation  componentOrientation, Component component){
    	if(lang!=null && !lang.trim().equals("")){
			Locale[] locales = Locale.getAvailableLocales();
			for(int i=0; i<locales.length;i++){
				java.util.Locale locale = locales;
		         if(locale.getLanguage().equals(lang)){
		        	 component.getInputContext().selectInputMethod(locale);
		        	 if(componentOrientation!=null){
		        		 component.setComponentOrientation(componentOrientation);
		        	 }
		         }
		    }
		}
    }

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new TestFrame().setVisible(true);
            }
        });
    }

}

عزيزي الصنعاني يبدو لي انك عضو قديم في المنتدى ، اذكر موضوعك عن الخاصية static استفدت منها ، مرحبا بعودتك :)

1
#6
العيافـي كتب:

هذا مثال مع اضافة تحسين للكود السابق

في الكود السابق يكون التغيير على مستوى JFrame

وفي الكود التالي لديك خياران اما ان تقوم بتغيير اللغة JFrame بالكامل باستخدام الامر التالي

setLanguage("ar", null, this);

او يتم التغيير على مستوى الحقل ، حيث يكون هناك حقول باللغة العربية و حقول اخرى باللغة الانجليزية، باستخدام الكود التالي

focusListener("ar", ComponentOrientation.RIGHT_TO_LEFT, fNameAField, lNameAField);
        focusListener("en", ComponentOrientation.LEFT_TO_RIGHT, fNameEField, lNameEField);

package test.language;

import java.awt.Component;
import java.awt.ComponentOrientation;
import java.awt.GridLayout;
import java.util.Locale;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;


/**
 * @author othman
 *
 */
public class TestFrame extends javax.swing.JFrame {

	private static final long serialVersionUID = 1L;



	public TestFrame() {
		setLayout(new GridLayout(1,2, 100, 50));
		setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        initComponents();

    }

    private void initComponents() {

    	JPanel enPanel=new JPanel(new GridLayout(2,2));
        JLabel fNameELabel=new JLabel("f-name");
        JLabel lNameELabel=new JLabel("l-name");
        JTextField fNameEField=new JTextField(20);
        JTextField lNameEField=new JTextField(20);
        enPanel.add(fNameELabel);
        enPanel.add(fNameEField);
        enPanel.add(lNameELabel);
        enPanel.add(lNameEField);

    	JPanel arPanel=new JPanel(new GridLayout(2,2));
    	JLabel fNameALabel=new JLabel("الاسم الاول");
        JLabel lNameALabel=new JLabel("الاسم الثاني");
        JTextField fNameAField=new JTextField(20);
        JTextField lNameAField=new JTextField(20);

        arPanel.add(fNameAField);
        arPanel.add(fNameALabel);
        arPanel.add(lNameAField);
        arPanel.add(lNameALabel);

        this.add(enPanel);
        this.add(arPanel);

//      هنا سيتم تحويل اللغة الى العربية عند انشاء الفورم
//    	setLanguage("ar", null, this);  

//        هنا يكون التحويل عند الدخول الى احد الحقول
        focusListener("ar", ComponentOrientation.RIGHT_TO_LEFT, fNameAField, lNameAField);
        focusListener("en", ComponentOrientation.LEFT_TO_RIGHT, fNameEField, lNameEField);

    	pack();
    	setLocationRelativeTo(null);



    }

    public static void focusListener(final String lang, final ComponentOrientation  componentOrientation, Component... components){
    	for(final Component component:components){
        	component.addFocusListener(new java.awt.event.FocusAdapter() {
                public void focusGained(java.awt.event.FocusEvent evt) {
                	setLanguage(lang,  componentOrientation, component);
                }
            });
    	}
    }


    public static void setLanguage(String lang, ComponentOrientation  componentOrientation, Component component){
    	if(lang!=null && !lang.trim().equals("")){
			Locale[] locales = Locale.getAvailableLocales();
			for(int i=0; i<locales.length;i++){
				java.util.Locale locale = locales;
		         if(locale.getLanguage().equals(lang)){
		        	 component.getInputContext().selectInputMethod(locale);
		        	 if(componentOrientation!=null){
		        		 component.setComponentOrientation(componentOrientation);
		        	 }
		         }
		    }
		}
    }

    /**
    * @param args the command line arguments
    */
    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new TestFrame().setVisible(true);
            }
        });
    }

}

عزيزي الصنعاني يبدو لي انك عضو قديم في المنتدى ، اذكر موضوعك عن الخاصية static استفدت منها ، مرحبا بعودتك :)

ما شاء الله عليك استاذي العيافي

ابدعت

وحليت مشكلة عانينا منها كثيراً

وصدق حدسي فمن غير المنطقي أن لا يوجد حل سهل لهذه المشكلة

وصدق حدسي مرة أخرى عندما ظننت أن لن أعدم في هذا المنتدى الطيب من يحل هذا الاشكال

وفعلاً استاذي انا نفسه العضو القديم

وحياكم الله

مودتي واحترامي

فالف شكر لك يا طيب

لا بد من صنعاء وان طال السفر

#7

كيف أمنع المستخدم من تغيير ال locale الخاصة ببرنامجي أثناء وقت العرض؟

(بمعنى آخر الضغط على shift+alt)

تحياتي

حزمة المحرك الإصدارة 0.8

أي أحد يجد أني ظلمته فليراسلني

وبإذن الله لو كان له حق سيأخذه

728x90.png

#8

عزيزي علاء

من الطرق استخدام الصنف PlainDocument لادارة القيم المدخله في الحقل (JTextField)

هذه اضافة بسيطة للتحقيق المطلوب على الصنف السابق .

        fNameAField.setDocument(new LocaleDocument(fNameAField, new Locale("ar")){
			private static final long serialVersionUID = 1L;
			@Override
			protected void setLocale(int offs, String string, AttributeSet a) {
				setLanguage(this.locale.getLanguage(), ComponentOrientation.RIGHT_TO_LEFT, fNameAField);
			}

        });

        lNameAField.setDocument(new LocaleDocument(lNameAField, new Locale("ar")){
			private static final long serialVersionUID = 1L;
			@Override
			protected void setLocale(int offs, String string, AttributeSet a) {
				setLanguage(this.locale.getLanguage(), ComponentOrientation.RIGHT_TO_LEFT, fNameAField);
			}

        });

        fNameEField.setDocument(new LocaleDocument(fNameEField, new Locale("en")){
			private static final long serialVersionUID = 1L;
			@Override
			protected void setLocale(int offs, String string, AttributeSet a) {
				setLanguage(this.locale.getLanguage(), ComponentOrientation.RIGHT_TO_LEFT, fNameAField);
			}

        });
        lNameEField.setDocument(new LocaleDocument(lNameEField, new Locale("en")){
			private static final long serialVersionUID = 1L;
			@Override
			protected void setLocale(int offs, String string, AttributeSet a) {
				setLanguage(this.locale.getLanguage(), ComponentOrientation.RIGHT_TO_LEFT, fNameAField);
			}

        });

وهذا الصنف يرث الكائن PlainDocument

import java.awt.Component;
import java.util.Locale;

import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.PlainDocument;

public abstract class LocaleDocument extends PlainDocument{

	private static final long serialVersionUID = 1L;

	protected Component component;
	protected Locale locale;

	public LocaleDocument(Component component, Locale locale) {
		this.component = component;
		this.locale = locale;
	}

	public void insertString(int offs, String string, AttributeSet a)throws BadLocationException {
		if(component.getInputContext().getLocale().getLanguage().equalsIgnoreCase(this.locale.getLanguage())){
			super.insertString(offs, string, a);
		}else{
			setLocale(offs, string, a);
		}
	}

	protected abstract void setLocale(int offs, String string, AttributeSet a);

}

يوجد هنا نقطة لم اتطرق اليها في المثال السابق، عند اضافة حرف بعد تغيير اللغة ستفقد هذا الحرف، بالامكان ايجاد طريقة لارجاع الحرف واضافتها مره اخرى للحقل

اعتقد بان هناك طرق اخرى مثل التحكم في shift+alt برمجيا، ولكن توجد بعض الاجهزه يكون تغيير اللغة بواسطة shift+ctrl ، وكذلك عند تغيير النظام .. لا اعلم هل هذا هو الحال في لينكس و الماك او تختلف.

1
#9

سلمت أخي عثمان

نردهالك في الأفراح إن شاء الله wink.gif

تحياتي

حزمة المحرك الإصدارة 0.8

أي أحد يجد أني ظلمته فليراسلني

وبإذن الله لو كان له حق سيأخذه

728x90.png

مواضيع مشابهة