Lite gui frågor i java (grindnätssimulator)

Permalänk
Medlem

Lite gui frågor i java (grindnätssimulator)

Tjena!

Det är så att jag gjort en grindnätssimulator för att simulera olika logiska kopplingar av grindar. Har precis blivit klart med allt utom gui.

Strukturen ser ut ungefär enligt följande

LogicGatesVector - innehåller en vector av typen LogicGate (se nedan) med alla tillagda grindar samt alla getters och setters man behöver. Alla gates har ett id som tilldelas vid skapandet av gaten. Detta id används för att hålla koll på vilka gates som är ihopkopplade med vad osv. Gate-id returneras vid skapande av en gate.

Har sedan en abstrakt klass som heter LogicGate där varje grind är en subklass.

LogicGate
- OrGate - Andgate - NotGate

Så långt är allting okej. Det jag inte har någon koll på är gui i java, eller egentligen gui alls. Hur ska jag bära mig åt för att kunna få något grafiskt av detta? Vill kunna dra runt grindarna i fönstret och koppla genom att mellan output, input osv.

Några tips?

Tack på förhand!

Visa signatur

-= Svettig dator och en hårig mobiltelefon =-

Permalänk
Medlem

Du får googla lite på java.awt.Graphics, paint, paintComponent så hittar du nog exempel.

Spontant utan att ha tänkt något djupare så skulle jag väl ha en huvud gui klass som ärver från java.awt.Panel (kalla den LogicGridPanel kanske?) och i den klassen overridar du metoden paint(Graphics g) sedan gör du metoder för att rita den grid du vill ha, och även metoder för att rita upp de olika logik kretsarna.

Kanske har varje krets en GUI motsvarighet som har en metod drawCircuit(Graphics g) metod där du alltså skickar in grafik objektet från LogicGridPanel och dessa "ritar sig själva" på det sättet. Varje sådan klass kan också ha metoder för move(x, y) ...etc

Mycket viktigt att tänka igenom strukturen och inte göra för mycket i varje klass men i grunden är det enkelt att rita.

Permalänk
Medlem

Precis sån vägledning jag behövde! Sitter och googlar men ser än så länge inte skogen för träden. Ska tänka igenom det du har skrivit

Visa signatur

-= Svettig dator och en hårig mobiltelefon =-

Permalänk
Medlem

Har experimenterat lite idag och kommit en bit på vägen. Provat graphics lite smått med lite kollisionshantering samt drawLine mellan objekt/bilder

https://www.dropbox.com/s/556c5lkajvqxsjm/linjer.PNG
https://www.dropbox.com/s/6qscu7ifr0lzlkd/conquerTheWorld.PNG

Funderar på hur jag ska knyta ett ID till ett av objekten/bilderna. Vid exempelvis "Assign swith to gate" vill jag kunna trycka på en switch och sedan trycka på en gate. De ska då kopplas ihop i logiken samt i grafiken. Någon som har något tips?

EDIT: Kom på att jag kan returnera ett värde vid dubbelklick. Ska experimentera vidare på det spåret
Något i den här stilen

if (e.getClickCount() == 2 && !e.isConsumed() && e.getX() >= myRect1.x && e.getX() <= myRect1.x + 50 && e.getY() >= myRect1.y && e.getY() <= myRect1.y + 50)

Visa signatur

-= Svettig dator och en hårig mobiltelefon =-

Permalänk
Medlem

Så där ja, då var man igång igen efter lite tentaplugg. Har fastnat på funktionen med att kunna returnera Id på den gate jag dubbelklickat på. Har en variabel enligt följande private int tmpId;

Citat:

for (int i = 0; i < myRect.size(); i++) {
if (e.getClickCount() == 2 && !e.isConsumed()
&& e.getX() >= myRect.elementAt(i).x
&& e.getX() <= myRect.elementAt(i).x + 200
&& e.getY() >= myRect.elementAt(i).y
&& e.getY() <= myRect.elementAt(i).y + 200) {

e.consume();
tmpId = gateId.elementAt(i);
clicked = true;
}

Har följande innanför MousePressed som i sin tur finns i min klass som heter MovingAdapter som extendar MouseAdapter. Funktionen i sig fungerar jättebra. tmpId får ett nytt värde om jag dubbelklicka på någon av de gates jag har utplacerade.

Problemet är att jag vill ha en metod i samma klass som returnerar tmpId. Någon som har en idé om hur denna kan implementeras? Måste ju på något vis vänta med att returnera värdet tills det att jag faktiskt har dubbelklickat.

Tack på förhand!

Visa signatur

-= Svettig dator och en hårig mobiltelefon =-

Permalänk
Avstängd

Ja det är väl inget enkelt projekt du gett dig in på precis Som jag ser det borde du ha det mesta av logiken liggandes i separata klasser och inte i gui.

Klassen för en gui kretsen kan se ut något sådant här till exempel:

public class CircuitGUI { private Circuit circuit; // Din krets som har all logik private Point location; // Gui kretsens x, y private Dimension size; // Gui kretsens storlek // Annat som behövs, färg kanske...etc // Konstruktor public CircuitGUI(Circuit c) { circuit = c; } public int getId() { return c.getId(); } public void draw(Graphics g) { // Rita med hjälp av grafikobjektet } public boolean isWithin(Point p) { // Kolla om p är inom ritade ytan, använd location och size } public void move(Point p) { location.x = p.x; location.y = p.y; } public void update() { // Kolla circuit state, uppdatera medlemsvariabler // eventuellt kör draw igen } }

Du har en sorts loop i gui delen:

1. paint ritar upp allt första gången
2. Något händer, ändras eller ett musklick, kolla igenom komponenterna och kolla om något var inom punkten
3. Uppdatera det som behövs
4. Kalla på repaint om det behövs

Du anropar alltså bara metoder i dina andra klasser för det mesta.

När ett musklick händer så letar du igenom och hittar kretsen med isWithin, du vet nu vilken krets det är och du gör det som ska göras och kör eventuellt repaint sedan för att visa vad som hänt.

Och du kommer säkert behöva göra så att guien lyssnar på status på kretsarna, så att guien vet att något hände och kan rita igen (observer..etc).

Om du inte vill rita kretsarna kanske varje krets kan vara en subklass av Panel eller något annat och du bara ritar en bild på den, då kan du nog ta emot musevent direkt i den klassen också.

Finns säkert andra på forumet som har bra idéer också, jag kommer nog tyvärr inte återkomma så ofta hit längre.

Lycka till med projektet !

Permalänk
Medlem

Min uppbyggnad är lite som du beskriver där i slutet. En logikdel med en klass vid namn LogicGates som håller en Vector innehållandes en abstrakt klass vid namn LogicGate som i sin tur har sub-klasserna and, or och not. Har testat logiken väl i consolen och den funkar fint

I Gui-klassen så har jag som innehåller knapparna samt rit-delen. Har även skapat ett objekt av typen LogicGatesVector där.

Så här ser det exempelvis funktionen ut när jag vill lägga till en gate. g1 är LogicGatesVectorn som jag skapat i Gui-klassen. returnerar ett id vid skapandet av en gate vilket även bilden i contentPanel3 tilldelas. contentPanel3 är själva rit-delen.

contentPanel3.addOr(g1.addOr());

Experimenterar lite med en fullösning där jag skickar in en referens till det aktuella gui-objektet när jag skapar min DrawSpace. Jag kan på så vis få ut Id på den gate jag dubbelklickat på i drawSpace. Circular dependency kallas det och är tydligen något som är satan själv inom programvarudesign
this.contentPanel3 = new DrawSpace(this);

Och ja, du har helt rätt. Det var inte det lättaste projektet att påbörja gui i java med. Det råkar bara vara något jag som gammal plc-programmerare varit väldigt sugen på att försöka mig på. Om inte annat så har jag något att garva åt i framtiden

EDIT: Själva ritytan har alltså ingenting med logiken att göra förutom att man kan returnera ett id som motsvara den Gate bilden är knuten till genom ett dubbelklick.

Visa signatur

-= Svettig dator och en hårig mobiltelefon =-

Permalänk
Medlem

Har fått det att funka nu. Går att spara till fil och läsa från fil med så jag är rätt nöjd. Helt klart en bra övning för att få lite koll på gui i java från att inte ha kunnat något

En bild på mitt mästerverk. Det jag inte är riktigt nöjd med och som jag ska fixa när jag orkar är att alla linjer blir röda när "lysdioden" är röd. Ska fixa i ordning så att enbart linjer vars källa är true blir röd.
https://www.dropbox.com/s/4l8bysfqegzzq8n/grindEXPORT.PNG

Tackar för all hjälp iaf! Det hjälpte mig mycket med var jag skulle börja

Visa signatur

-= Svettig dator och en hårig mobiltelefon =-