האם זה תכנות נכון?

הצלוי

New member
שאלה נוספת: GUI

טוב, אחרי שחשבתי איך לעצב את התוכנית וכתבתי את המחלקות, מגיעה השאלה איך להראות את הכל למשתמש.. למי שלא יודע דרך אגב, מדובר על כמה פילוסופים שיושבים מסביב לשולחן עם צלוחיות אורז מולם, ובין כל שני פילוסופים יש מקל סיני. כל פילוסוף אוכל וחושב באיזשהיא צורה, וכו'... הבעיה עכשיו היא איך להראות את כל זה למשתמש. אני חייב לציין שזה אחד החסרונות הגדולים שאני רואה בג'אווה (אני מבין שיש עוד דברים חשובים יותר כמו יעילות וכו', אבל בכל זאת..) וזה GUI בשפה שמנסה להיות כמה שיותר ניידת. בויז'ואל בייסיק הייתי יכול פשוט לצייר כל דבר בממשק. אבל פה אני צריך להשתגע עם Layouts... ונחזור לענייננו, איך אני אצייר על המסך שולחן, ומסביבו אובייקטים של פילוסופים ומקלות סיניים?? יש Layout מתאים לבעיה הזאת? (ובבקשה אל תגידו GridbagLayout...)
 

DadleFish

New member
הממממ

קודם כל, layouts זה רעיון מבריק שמפשט לך מאוד את החיים. אני מודה שזה לא כל כך פשוט להיכנס לראש של ה-layouts השונים - אבל מצד שני, אני פשוט נדבקתי ל-layout אחד ספציפי (זה עם הכיוונים, North-south וכו') וגיליתי שאפשר בקלות יחסית לעשות איתו כל דבר שרוצים. כמה פילוסופים יש לך?
 

הצלוי

New member
BorderLayout קוראים לו../images/Emo13.gif

הוא באמת הכי שימושי, וגם האחרים מאוד שימושיים. הבעיה היא שאי אפשר לשייך _כל_ תצוגה לlayout כלשהוא... חוץ מGridbagLayout אולי, והוא ממש ממש מסובך (לטעמי..)- אני לא מצליח לעבוד איתו. עקרונית בשאלה צריך 5 פילוסופים.. הייתי רוצה שזה יהיה יותר כללי (כמו לקחת את מספר הפילוסופים מהמשתמש בהתחלה), אבל אם אין ברירה, אני אסתפק בחמישה...
 

voguemaster

New member
אפשר

זה דורש ניסיון. אתה יכול לעבוד בלי layout או עם אחד שהוא פשוט ו"לצייר" את הממשק שלך בעזרת JBUILDER לדוגמא. זה עובד אבל זה לא משהו. ע"י שימוש נכון ב-layouts וב-panels אתה יכול לעשות דברים מדהימים. מעולם לא הצטרכתי gridbag ואני בספק אם אני אצטרך. דווקא ה-LAYOUTS בשילוב הרעיון של PANELS ו-CONTENT PANES הוא אחד היתרונות הגדולים ביותר שיש לג'אווה. כך לדוגמא אני יכול ליצור תוכנית בנוסח ACDSEE בחצי שעה של קידוד נטו. (אם כי יותר פשוטה מ-ACDSEE).
 

DadleFish

New member
גם אני חשבתי כמוך בהתחלה,

וחשבתי ש-Gridbag הוא הפתרון היחיד - זה טבעי לחשוב ככה כשרגילים לתכנן GUI על הפיקסל. מסתבר ששום תצוגה לא קשה מדי ל-BORDER. צייר משהו ואראה לך איך אתה עושה את זה כמו שצריך
 

הצלוי

New member
אני אנסה...../images/Emo13.gif

קח את דוגמת הפילוסופים.. המקלות לא חייבים להיות באלכסון.. ואם אפשר לעשות את זה כללי יותר (במקום חמישה פילוסופים כמה שאני רוצה...) אז זה בכלל יהיה מגניב
 

DadleFish

New member
חלק את זה ככה:

1. NORTH 1.1. EAST 1.1.1 ב-NORTH שים פילוסוף 1.2. WEST 1.2.1 ב-NORTH שים פילוסוף 2. SOUTH 2.1. EAST 2.1.2 ב-NORTH שים פילוסוף 2.2. WEST 2.2.2. ב-SOUTH שים פילוסוף 2.3. ב - SOUTH שים פילוסוף
 

הצלוי

New member
../images/Emo6.gif

נסה לצייר את זה על דף: בכל רמה של האלגוריתם הזה (בערך) חלק אותו שוב ותקע איפה שכתוב. אפשר לצייר את זה ככה שזה ייראה בסדר לפי השיטה הזאת, למרות שזה ייראה קצת עקום
ואתה חייב להודות שזה יהיה הרבה יותר בעייתי אם ארצה לעשות 8 או 9 פילוסופים... וזה בכלל בעייתי מאוד אם אני רוצה לקלוט את מספר הפילוסופים מהמשתמש... במקרה הזה הסתדרתי, כי אמרו לי שאני יכול פשוט לצייר את העצמים (עם Graphics) במקום להתעסק עם כל הJPanels, אבל זה מראה שיש תצוגות שקשה מאוד לעשות עם Layouts...
 

הצלוי

New member
גם אני חושב שכן

פשוט לא כל כך טוב....
לפי דעתי, ג'אווה מתוכננת להיות כמה שיותר protability-ית (מה התרגום של זה לעברית? ניידת?), ולכן היא מנסה לעשות הוספות GUI כמה שיותר כלליות. זה מקשה מאוד על המתכנת בתצוגות קשות ל"הכללה", אבל זה דבר מאוד חכם שהיא יכולה להתאים את הGUI לכל מצב של החלון ובכל מערכת הפעלה...
 

DadleFish

New member
אני אשמח להרחבות -

אני לא רואה איך אפשר לעשות ב-JAVA אלמנטי GUI יותר מתוחכמים. בא לך להסביר?
 

voguemaster

New member
מה אתה צריך ? זו תמיד השאלה.

במקרה של הבחור הצעיר פה למעלה, אפשר תמיד ליצור משהו שנקרא CenteredCircularLayout שבו יש לך JPanel מסוים שבמרכזו (או באוריינטציה אחרת בתוכו) אתה ממקם "נקודה" וסביבה ממקם JComponents. לא קשה בכלל. זה מפשט מאוד יצירת שעון מחוגים
 

הצלוי

New member
"הבחור הצעיר פה למעלה"../images/Emo6.gif

מצחיק שיש אנשים שקוראים לי זקן...
עקרונית כבר סיימתי את המטלה, אבל סתם מתוך סקרנות אשמח לדעת איך אפשר ליצור משהו כזה?
 

danbars

New member
קצת סדר

אומנם כבר כתבת את שתי המחלקות, אבל בכל זאת קצת סדר: כשאתה משתמש בג'אווה ב-synchronized, זה אומר שאם מישהו מריץ את הפונקציה שמוגדרת כ-sync אף אחד אחר (כלומר אף thread אחר) לא יכול להריץ אותה. ניתן להגדיר פונקציה כ-sync או בלוק בתוך פונקציה כ-sync. למשל:
public void synchronized doIt() {/*some code*/}​
זהה כמעט לחלוטין לקוד:
public void doit() { synchronized(this) { /*some code*/ } }​
מה שקורה מאחורי הקלעים בקוד הנ"ל הוא זה: לכל אובייקט במערכת יש Mutex ("מנעול"). כשמריצים קטע קוד sync, אז ה-Thread שמריץ את הקוד תופס את המנעול של האובייקט, ולכן אף thread אחר לא יכול להריץ אף קטע קוד אשר דורש שימוש במנעול של אותו אובייקט (גם אם זו פונקציה אחרת שהיא sync על אותו אובייקט). אם בתוך הקטע המסונכרן ה-thread נרדם (למשל בשל פקודת wait), אז המנעול משתחרר ו-thread אחר יוכל להיכנס לתוך הקוד. ה-thread המקורי במקרה זה לא יוכל להמשיך עד שהמנעול ישוחרר על ידי ה-thread השני. לדעתי אין לך צורך לשמור את הפילוסוף בתוך האובייקט של המקל (למרות שזה ניתן. ג'אווה יודע לקמפל קלאסים המצביעים אחד על השני ללא שום בעיה). גם אם תחשוב מבחינה לוגית (על המצב האמיתי אותו אתה מייצג), הפילוסוף יודע איזה מקל הוא מחזיק, אך מקל לא "יודע" מי מחזיק אותו. מספיק אם תסמן flag שיגיד אם המקל תפוס או לא. כשפילוסוף ינסה להרים מקל שכבר תפוס, תוכל לבדוק את הפלאג הזה. גם אם הוא ינסה להרים בלי לבדוק, והמקל יהיה תפוס, הוא לא יצליח כי פונקציית הרמת המקל אמורה להיות sync על האובייקט של המקל. בנוגע לגרפיקה בג'אווה. השימוש ב-layouts באמת דורש התרגלות לעניין. הדרך הכי טובה ופשוטה היא להשתמש באפליקציה בעלת עורך גרפי, המייצרת את הקוד הדרוש לצייר את מה שסימנת באופן גרפי (כמו עורך של VB). ניתן להוריד בחינם (לשימוש אישי) את jbuilder (אחת האפליקציות הכי מקצועיות שקיימות), או אחת ממאות תוכנות אחרות (חפש כאלו עם עורך גרפי). אם אתה מתעקש לעשות את זה לבד, תוכל להשתמש ב-layoutXY (אני לא זוכר אם זה בדיוק השם שלו, אבל הוא מאפשר לך לצייר עצמים על ידי ציון מיקומם ב-xy, ולא על ידי חלוקת ה-layout ל-layout נוספים או ל-panel כפי שנדרש ברוב ה-layout האחרים.) מקווה שעזרתי. בהצלחה !
 

הצלוי

New member
עזרת מאוד אפילו../images/Emo13.gif

אבל אני רוצה להבהיר משהו בקשר לdesign. מצד אחד אתה צודק שמקל "לא צריך לדעת" מי מחזיק אותו. אבל מצד שני, בוא אני אתאר לך את המצב הבא: פילוסוף 1 לוקח את המקל הסיני. פילוסוף 2 "מתבלבל" ומנסה לעזוב את המקל הסיני, למרות שאין לו אותו בכלל. במקרה הזה, המקל הסיני לא יבדיל בין שני הפילוסופים ולא ייעשה שום דבר בנידון. הוא ייתן לפילוסוף 2 לעזוב אותו, למרות שהוא לא אצלו בכלל. ופילוסוף 1 ימשיך לחשוב שיש לו אותו, למרות שהוא בכלל עזוב...
 

danbars

New member
פתרון

אז שפילוסוף לא יתבלבל: לפני שהוא מנסה לעזוב מקל שיבדוק אם הוא אצלו (הרי הפילוסוף יודע איזה מקלות הוא מחזיק). המקל עדיין לא יצטרך לדעת מי מחזיק אותו. הערה כללית (נכונה לכל תוכנה): אם הקוד שלך סותר את ההיגיון, כנראה שיש לך בעיה בתכנון, וכדאי לך לפתור אותה לפני שאתה מתחיל לכתוב קוד, אחרת תאכל הרבה קש כשתגיע לכתיבת הקטע הבעייתי. במקרה הזה, יש כאן חוסר היגיון שמקל חייב לדעת מי מחזיק אותו. נסה להבין למה אתה חייב שמקל ידע מי מחזיק אותו, ופתור את הבעיה. כן ?
 

הצלוי

New member
כן, כמובן

שאני אשמור על הפילוסופים שלי כמו שצריך
אבל אני מנסה לעשות תוכנית כמה שיותר יפה וObject Oriented-ית... המקל הסיני צריך להיות כמה שיותר עצמאי..נניח מישהו מחר יישמע על תוכנית בעיית הפילוסופים המדהימה שלי וירצה לפתח אותה.. והוא יהיה מתכנת אדיוט ולא ישמור על הפילוסופים שלו.. אני רוצה שהמקל הסיני יהיה כמה שיותר עצמאי ויידע לשמור על עצמו, גם כשאני לא זה שמתכנת..
 
למעלה