Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Fr Jul 11, 2025 21:33

Foren-Übersicht » Programmierung » Allgemein
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 10 Beiträge ] 
Autor Nachricht
BeitragVerfasst: Sa Jan 10, 2009 22:53 
Offline
Guitar Hero
Benutzeravatar

Registriert: Do Sep 25, 2003 15:56
Beiträge: 7810
Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Ich befinde mich bei meiner JOGL_GUI in einem recht weit fortgeschrittenen Zustand.
Letzte Woche ist es mir gelungen eine scrollbare Komponente zu implementieren. Mit der kann ich jetzt theoretisch beliebig viele Daten in einem begrenzten Raum anzeigen.

Der letzte Programmierschritt vor der Vorstellung des Projekts ist eine scrollbare Tabelle.
Vor diesem Brocken sitze ich jetzt schon eine Weile und grüble, wie ich das so designe, dass es simple zu nutzen ist, wenig Code benötigt - vor allem wenig Sonderfallbehandlungen, und am besten auf Bestehendes aufbaut.

Ich schildere erstmal was die Tabelle können soll:
- vertikal feststehende Kopfzeile (Tableheader) -> aber horizontal scrollbar
- horizontal feststehende Kopfspalte (Tableheader) -> aber vertical scrollbar
- ob und welche Header sichtbar sind, soll einstellbar sein.
- Datenbereich 2dimensional scrollbar.
- Tabellenzellen können Text oder eine beliebige andere Komponente (z.B. Button) enthalten.
- Tabellenzellen sollen festlegen ob sie einen Rahmen haben und wie dick dieser ist und in welcher Farbe.
- Tabellenzellen sollen ein Padding haben und eine beliebige Hintergrundfarbe

Meine bisherigen Überlegungen:
- Die Tabelle soll von der TglScrollComponent abgeleitet werden. Diese kann bereits genau 1 Komponente beliebiger Größe scrollen. Auf diesem Scrollbereich sollen die Zellen abgelegt werden. Zusätzlich zum Datenbereich sollen zwei weitere Bereiche definiert werden, welche die Headerzeile bzw. spalte enthalten soll. Diese sollen über die Scrollbars des Datenbereich mitgescrollt werden, allerdings nur in die, für den jeweiligen Header zulässige, Richtung.
- Die Zellen werden durch eine eigene Klasse "TglTableCell" abgebildet. Von dieser Klasse gibt es zwei unterformen: "TglTableTextCell" und "TglTableComponentCell".


So. Das klingt ja bisher alles ganz fluffig. Allerdings kam ich in meinen Gedankenexperimenten an die Stelle, wo ich Daten in die Tabelle füllen wollte. Wie mach ich das am besten?
Ich mein, wie sollte man am besten mit einer Tabelle arbeiten können, damit sie praktisch ist.
Und wie sollte man es einrichten, dass man solche Sachen wie Padding, Hintergrundfarbe, Border etc. für alle Zellen einer Zeile resp. Spalte setzen kann.

Mir fehlt hier konkret noch die nichtsichtbare(n) Datenstruktur(en) die im Hintergrund die Daten halten und die Getter und Setter dafür.

Für Inspiration wäre ich dankbar.

_________________
Blog: kevin-fleischer.de und fbaingermany.com


Nach oben
 Profil  
Mit Zitat antworten  
BeitragVerfasst: So Jan 11, 2009 09:53 
Offline
DGL Member

Registriert: Do Mai 30, 2002 18:48
Beiträge: 1617
Flash hat geschrieben:
Mir fehlt hier konkret noch die nichtsichtbare(n) Datenstruktur(en) die im Hintergrund die Daten halten und die Getter und Setter dafür.

Am besten gar keine :lol: ... Würde dafür Events nehmen, die erfragen, was denn bitte in der Tabelle in Zelle x,y drin steht und evtl. sogar ein draw zur verfügung stellen - das erhöht die Flexibilität von solchen Tabellen dramatisch. Weil im Prinzip hast Du ja keine Ahnung, ob die Tabelle dünn oder stark bestzt ist, und Du vielleicht versuchst mit völlig falschen Methoden die Daten zu halten. Kannst ja dann immernoch eine weitere Klasse ableiten, die ein 2D-Array von Strings trägt, in das man seine Daten hineinlegen kann. Wenn es außerdem eine Möglichkeit gibt, sicht+interagierbare komponenten in die Zellen hineinzulegen ist das auch immer nicht schlecht....


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Jan 11, 2009 11:59 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Ja, der Ansatz von Nico ist denke ich ganz gut.

Du kannst dabei am besten mal in die TVirtualTreeView von Mike Lischke reinschauen. Das ist zwar ein Treeview, aber mit einem Optionsswitch kannst du daraus ein Grid machen... Ist also Mächtig das ding. Das arbeitet auch nach dem Prinzip für-alles-ein-Event. Im Prinzip hat das ding garkeine wirklichen Datenstrukturen (außer interne, die die Verkettung der Elemente angben) und ruft beim Zeichnen immer per Events alles ab, was es braucht. Zusätzlich hat der Benutzer die möglichkeit, einen Pointer oder ein Record in den genannten internen Strukturen abzulegen und aus diesen abzurufen, sodass man sich selber trotzdem eine menge aufbauen kann.
Zum Beispiel legt man in jedem Node ein Objekt ab, welches Methoden für GetText, Paint und ähnliches hat. Dann behandelt man die Events, indem man sich den Pointer auf das Objekt rausreichen lässt und die entsprechende Methode im Objekt aufruft.

Für deine Tabelle würde ich sagen, ist das auch ein garnicht so schlechter ansatz. Du könntest ein 2D-Array aus Feldern erstellen, wo du platz für einen Pointer lässt. Und dann beim erzeugen der Tabelle bzw beim Festlegen der Größe rufst du dann ein Event auf, welches die möglichkeit hat, einen Pointer zurückzugeben, der dann in deiner Struktur abgelegt wird.
Beim Zeichnen rufst du dann ein Event auf, welches die Koordinaten übergeben bekommt und einen Text zurückliefert oder so. Oder einfach nur ein Paint event. Oder was-auch-immer.

Dann könntest du davon eine Klasse ableiten, die diese Events selber überschreibt und dann Anstatt eines einfachen Pointers Referenzen auf Objekte annimmt oder sowas. Ich glaube, da sind der Phantasie keine Grenzen gesetzt.

Gruß Lord Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Jan 11, 2009 12:02 
Offline
DGL Member
Benutzeravatar

Registriert: Sa Dez 28, 2002 11:13
Beiträge: 2244
Für den Datenbereich könnte man vielleicht so eine Schnittstelle verwenden:

Die Tabelle enthält ein 2D Array mit den gerade sichtbaren Zellen.
Wenn gescrollt wird (oder am Anfang) werden die Zellen neu aus dem Model angefordert.

Code:
  1. interface ITableModel
  2. {
  3.   int GetRows();
  4.   int GetColumns();
  5.   TglTableCell GetCell(int row, int column);
  6. }

Eine Klasse die z.B. das kleine 1x1 anzeigt, sähe z.B. so aus.

Code:
  1. public class TestModel implements ITableModel
  2. {
  3.     public int GetRows()
  4.     {
  5.         return 10;
  6.     }
  7.  
  8.     public int GetColumns()
  9.     {
  10.         return 10;
  11.     }
  12.  
  13.     public TglTextCell GetCell(int row, int column)
  14.     {
  15.         return new TglTextCell(((row+1) * (column+1)).toString());
  16.     }
  17. }


Ein Kritikpunkt wäre, dass hier die Daten und deren Darstellung nicht voneinander getrennt sind. Daher ist die Klasse eigentlich kein Model sondern ein ViewModel. Falls man dies benötigt wäre es über ein Adapter möglich. Davon braucht aber die Tabelle nichts zu wissen.

z.B. wäre ein ViewModel denkbar, dass seine Informationen über Reflection ermittelt und man über Annotationen festlegt, wie ein Feld dargestellt werden soll.

Vermutlich braucht man keine Benachrichtigungen, da bei OpenGL sowieso immer alles gezeichnet wird. Ansonsten kann so ein Modell optional noch Observable implementieren.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Jan 11, 2009 16:18 
Offline
Guitar Hero
Benutzeravatar

Registriert: Do Sep 25, 2003 15:56
Beiträge: 7810
Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Also danke erstmal für die Antworten.
Zuerst zu Lars:
Du würdest es also so machen, dass alle Daten die in einer Tabelle angezeigt werden sollen in einer beliebigen Datenstruktur liegen, hauptsache diese DS bietet ein Interface an, aus dem dann die Tablle z.b. zum Rendern die Daten liefert?

Das ist keine schlechte Idee. Wenn ich die Idee dahingehe ausbaue, dass es ein ITableModel gibt von dem ein ITableModelText und ein ITableModelComponent abgeleitet wird, dann könnte das ein interessanter Ansatz werden.

@Nico und L.H.:
So richtig verstanden hab ich eure Idee noch nicht. Könntet ihr eventuell mal einen Pseudokode tippen wie man mit einer Tabelle umgehen soll die eurem Prinzip folgt? Dann wirds vielleicht klarrer.

_________________
Blog: kevin-fleischer.de und fbaingermany.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: So Jan 11, 2009 17:05 
Offline
DGL Member
Benutzeravatar

Registriert: Di Okt 03, 2006 14:07
Beiträge: 1277
Wohnort: Wien
Hallo Flash,

Na, zum Beispiel eine Objektliste.
Jedes Objekt kennt seinen Index(X/Y) in der Tabelle; sortiert sind sie nach X und innerhalb der X nach Y (oder umgekehrt, je nach Geschmack). Auf diese Art sind sie mit einem schnellen Suchalgorithmus gut wiederzufinden. Leere Zellen brauchen keinen Eintrag. Fürs Einfügen und Löschen von Zeilen und Spalten muss man dann ein wenig tüfteln.

In den Spalten stecken dann die Zellinhalte als Objekt: ein Objekt mit seinen eigenen Daten, Methoden und Ereignissen: z.B. „OnDrawCell“, was Du eben brauchst.

Ah ja, und nicht vergessen: wenn die Zellen editierbar sein sollen, sollte man ein Undo einbauen. Ich sage das, weil man das Undo am Besten von Anfang an berücksichtigt, denn später einbauen wird immer ein Krampf.

Das Interface fürs Rendern ist natürlich gut, wenn man verschiedene Graphic Bibliotheken „dranstecken“ will, muss aber nicht sein.

Traude

EDIT: Entschuldigung, es muss natürlich oben heißen: "In den Objekten stecken dann die Zellinhalte" und nicht "In den Spalten stecken dann die Zellinhalte als Objekt". Es sollen ja gerade eben keine Spalten sein.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mo Jan 12, 2009 13:23 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Um meinen Vorschlag zu verdeutlichen:
Code:
  1.  
  2. // Pseudocode
  3. function drawCell()
  4.   clearCellBackground // eventuell, wird ja wahrscheinlich zusammen mit
  5.                       // dem ganzen rest ausgelöscht, wenn du nicht mit Invalidate arbeitest
  6.   callEvent('afterClean', CellPointer)
  7.   text = retreiveTextViaEvent('getText', CellPointer)
  8.   callEvent('beforePaint', CellPointer)
  9.   if (not callEvent('drawCell', CellPointer))
  10.     drawCellBorder
  11.     drawCellContents(text)
  12.   callEvent('afterPaint', CellPointer)
  13. end
  14.  

CellPointer ist halt jeweils ein Pointer, der genau die Zelle beschreibt. Ich würde sagen, dass das eigentlich drei Werte sind: X, Y und Pointer auf die Zellstruktur, woraus man dann eventuell ein Userdata-Feld bekommen kann oder so.

So sähe dann eine Zeichenmethode nach dem Virtual Paradigm aus. Wie gesagt, schau dir am besten mal die VirtualTree View Komponente. Du musst dir ja nicht die > 1MiB Source code reinziehen, allein die Dokumentation gibt schon eine menge Auskunft. Ich kann dir ja mal ein Projekt zukommen lassen, wo ich die VirtualTreeView-Komponente verwende und anspreche, dann siehst du vielleicht besser, was ich meine. Allerdings wird das noch einen Moment dauern, da ich gerade in der Schule sitze und dementsprechend wenig Zugriff auf meine Projekte habe.

Gruß Lord Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Jan 13, 2009 22:30 
Offline
Guitar Hero
Benutzeravatar

Registriert: Do Sep 25, 2003 15:56
Beiträge: 7810
Wohnort: Sachsen - ERZ / C
Programmiersprache: Java (, Pascal)
Also, ich habe jetzt eine Weile darüber nachgedacht und rausgekommen ist eine ziemlich tolle Skizze auf der Rückseite eines Briefumschlags und die Idee mal eine (wie ich denke) ordentliche Model View Controller Architektur in einem Tutorial zu erklären.

Ich denke ich werde die Idee von Lars aufgreifen und ein Interface für das GUI Interne Datenmodell anbieten. Das Werde ich in 2 Ausführungen anbieten. Für Text und für Komponenten. Über das Komponenteninterface kann die Tabelle dann Ereignisse (Mouseclick etc) an die Componenten weiterleiten.

Ich hatte mir sorgen gemacht, dass der Umgang mit der GUI (bzw. Tabelle) zu viele Klassen nötig macht. Aber wie man in der Skizze sieht, sind dafür die GUI Controller der Anwendung zuständig. Und die müssen ja sonst nicht viel mehr machen. 8)


Du hast keine ausreichende Berechtigung, um die Dateianhänge dieses Beitrags anzusehen.

_________________
Blog: kevin-fleischer.de und fbaingermany.com


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Di Jan 13, 2009 22:38 
Offline
DGL Member

Registriert: Do Mai 30, 2002 18:48
Beiträge: 1617
:shock: ist das der erkundungsplan einer expedition ins innere einer pyramide? Ich kann fei gar nix lesen :twisted:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags:
BeitragVerfasst: Mi Jan 14, 2009 11:56 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Wo ist das kreuz, wo ist das kreuz, ich will den Schatz finden. Oh... Ist ja garkeine Schatzkarte ;)

Letzendlich läuft es dann ja auf das gleiche hinaus wie bei den Events, nur dass das ganze in Interfaces gekapselt ist. Auch nicht schlecht.

Gruß Lord Horazont

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 10 Beiträge ] 
Foren-Übersicht » Programmierung » Allgemein


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 16 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.010s | 15 Queries | GZIP : On ]