Suche Programmierer oder viel Hilfe

Hallo,
eigentlich habe ich schon einiges an Programmiererfahrung (PHP, Delphi, C++, Pascal) hinter mir, aber an Java kann man schon ein wenig verzweifeln. Als Entwicklungsoberfläche habe ich NetBeans momenten gewählt.

Ich wäre sehr froh wenn ich jemand finden würde, der mir mein kleines Analyseprogramm schreibt. Sollte sich niemand finden lassen, hoffe ich auf sehr viel Geduld. Probleme bereitet mir dabei primär die grafische Benutzeroberfläche. Ich brauche:

a) Menüleiste mit zwei direkt auswählbaren Einträgen - eine zum Sprache umwechseln und eine zum Schließen. Den Umweg über File > Schließen will ich nicht nehmen.

b) Eine Progressbar (in der Statusleiste enthalten)

c) Ein Explorer (ähnlich Windows Explorer in Baumstruktur), um Ordner auswählen zu können.

d) Ausgabe in einem Säulendiagramm (notfalls auch nur in Textfeldern)

Die Funktionsweise des Programms ist relativ leicht:
Es soll den ausgewählten Ordner rekursiv durchsuchen und von allen Dateien die Anfangsziffer der Dateigröße analysieren. Ziel ist die Ausgabe der absoluten und relativen Häufigkeit.

Bin gespannt auf eure Antworten.

Gruß DuAK007

Hallo,

Ich will dir zumindest mal ein Paar Stichwörter liefern, mit denen du z.B. auf einer der beiden Seiten was finden solltest:
http://openbook.galileocomputing.de/javainsel8/stich…
http://java.sun.com/javase/6/docs/api/

Das sind zumindest meine Standard-Nachschlagewerke. Anfangs mehr das erste, später fast nur noch das zweite. Auch Sun bietet teilweise sehr ausführliche Tutorials an.
Ich gehe hier davon aus, dass du Swing benutzt (oder zumidest AWT), mit anderen Window Toolkits habe ich noch nicht gearbeitet.

a) Menüleiste mit zwei direkt auswählbaren Einträgen - eine
zum Sprache umwechseln und eine zum Schließen. Den Umweg über
File > Schließen will ich nicht nehmen.

Menüleisten werden mittels JMenuBar gemacht. Ein Programm, das für mehrere Sprachen geeignet ist, habe ich ehrlichgesagt noch nie ernsthaft in Angriff genommen. Aber auch hier gibt es Möglichkeiten; du könntest dir selbst was ausdenken (das geht, ich habe schon zwei Lösungen dazu gesehen, eine stammt von mir, aber wie gesagt, nie ernsthaft verwendet). Oder du greifst auf eine fertige Library zurück. Mangels Erfahrung kenn ich nur eine, und die auch nur vom Namen: GNU gettext.
Falls die Sache mit dem Schließen sich auf dein Fenster bezieht, könntest du auch einfach den Schließen-Knopf rechts oben am Fenster verwednen.

b) Eine Progressbar (in der Statusleiste enthalten)

Ja, auch Progressbars gibt in Swing (JProgressBar). Dummerweise ist Swing nicht threadsicher. Dazu würde ich dir das hier ans Herz legen:
http://java.sun.com/docs/books/tutorial/uiswing/comp…

c) Ein Explorer (ähnlich Windows Explorer in Baumstruktur), um
Ordner auswählen zu können.

Hm… ein File-Browser mit Baumstruktur? Ich kann mich nicht erinnern, soetwas schon mal gesehen zu haben. Aber es gibt einen normalen File-Browser: JFileChooser.

d) Ausgabe in einem Säulendiagramm (notfalls auch nur in
Textfeldern)

Tja, auch an ein Säulendiagramm kann ich mich nicht entsinnen, was aber vermutlich daran liegt, dass ich sowas noch nie gebraucht habe. Ich will nicht ausschließen, dass es da schon etwas vorgefertigtes gibt, zur Not mal googlen. Ansonsten musst du selber ran: Du kannst in Swing malen. Also könntest du ein paar Rechtecke und ein paar Zalen dran malen. Dazu gibts in der Insel ein ganzes Kapitel:
http://openbook.galileocomputing.de/javainsel8/javai…

Die Funktionsweise des Programms ist relativ leicht:
Es soll den ausgewählten Ordner rekursiv durchsuchen und von
allen Dateien die Anfangsziffer der Dateigröße analysieren.
Ziel ist die Ausgabe der absoluten und relativen Häufigkeit.

Jetzt wirds interessant. Die Anfangsziffer der Dateigrößen? Du willst nicht zufällig prüfen, ob das Benfordsche Gesetz für Dateigrößen gilt? Auf das Ergebnis wär ich gespannt.
Also Dateien und Ordner werden in Java durch die Klasse File repräsentiert. Und die kann auch alles was du brauchst. Z.B. über die listFlies(…)-Methoden den Inhalt eines Ordners rückgeben, mit isDirectory() prüfen, ob ein File ein Ordner ist (das könntest du für deine Rekursion gebrauchen) und ich *glaube* über length() kriegst du die Dateigröße, auch das habe ich noch nie benutzt.
An die Anfangsziffer kann man tatsächlich kommen. Du könntest z.B. die Zahl so lange durch 10 teilen, bis das Ergebnis 0 ist und dann den letzten Wert nehmen (ich hoffe ich mache hier keinen Denkfehler). Oder du kannst schummeln und das ganze in einen String konvertieren, dann davon das erste Zeichen nehmen und wieder ein int draus parsen. Nicht schön, nicht schnell, aber für leute, die nicht gern rumfrickeln oder abstrakt mathematisch denken evtl. einfacher.

Viel Erfolg und ich hoffe ich bekomme das Ergebnis mal zu sehen.

yYy

Hi und Danke für die erste Rückmeldung. In der Tat will ich das Benford-Gesetz damit überprüfen wollen. Ein solches Programm besitze ich auch schon - allerdings nur auf Deutsch und mit Delphi programmiert. Da wir aber das Programm ins Englische übersetzen wollen besteht die Notwendigkeit zum Neuprogrammieren, weil ich den Quelltext nicht besitze. Und wenn man gerade dabei ist, wäre eine Plattformübergreifende Version wünschenswert.

Aber woher soll ich wissen, welches Toolkit ich benutze? Ich klick auf „Desktop-Anwendung“ und alles ist da. Aber nach dem ich das hier gelesen habe… woher weiß ich, welche Befehle Plattformunabhängig sind? Ist das Java generell oder nur spezifische Funktionen? Besonders beim Zugriff auf die Dateien seh ich Probleme.

Das mit dem Menüeintrag ist leider immer noch das Problem. Selbst wenn ich beim Schließen auf das X verweisen kann, funktioniert das mit dem Sprachenwechsel nicht. Nachdem ich gestern über 2 Stunden danach krampfhaft gesucht habe, glaub ich fast dass die Komponente dazu nicht in der Lage ist. (Alle anderen Programmiersprachen die ich verwendete konnten das)

Das mit dem selber Zeichnen der Progressbar und des Diagramms sind wohl am sinnvollsten. Auch weil man dann in die Details gehen kann. Vielleicht zeichne ich dann auch gleich noch eine Baumstruktur. Denn so ein Dialogfenster ist für mein Vorhaben nicht gerade Benutzerfreundlich.

Wenn die Plattformbedingten Probleme erledigt sind (Datei- und Ordnerzugriff, Steuerung des Programms) wäre der Rest - also die Verarbeitung der Informationen - ein Kinderspiel. Denn da unterscheiden sich die Sprachen wenig.

Aber woher soll ich wissen, welches Toolkit ich benutze?

Naja, ja nach dem welche Komponenten du für dein Fenster benutzt. Als Basisfenster würde sich z.B. ein javax.swing.JFrame anbieten, alle Komponenten, die in javax.swing stehen, bilden das Swing-Toolkit. Java bringt von sich aus zwei Window-Toolkits mit, das andere ist AWT, das Abstract Window Toolkit. Das ist was älter und sieht nicht so schick aus, ist aber thread-sicher.
Eine Alternative wäre z.B. das Standard Widget Toolkit, das für eclipse entwickelt wurde. Allerdings ist das nicht in Java enthalten und du müsstest es mitliefern. Laut Wikipedia scheint es außerdem ja nach System Performance-Einbußen zu geben (also eclipse läuft auf meinem Ubuntu einwandfrei):
„Allerdings leidet SWT auf einigen Nicht-Windows-Plattformen unter Effizienzproblemen, da es viele Features eines Basistoolkits voraussetzt, welche – wenn nicht vorhanden – emuliert werden müssen.“

Aber nach dem
ich das hier gelesen habe… woher weiß ich, welche Befehle
Plattformunabhängig sind? Ist das Java generell oder nur
spezifische Funktionen? Besonders beim Zugriff auf die Dateien
seh ich Probleme.

Java ist fast komplett Plattformunabhängig, sofern es für das Zielsystem eine VM gibt. Unterschiede findet man z.B. im Input-Handling, denn java kann auch nur das verarbeiten, was das Betriebssystem ihm gibt. So kann z.B. die Reihenfolge oder die Art der Events differieren, die du erhältst, wenn du eine Taste drückst, oder gedrückt hältst.
Aber der Dateizugriff ist komplett unabhängig, solange du nicht versuchst, einen Absoluten Pfad hardzucoden. Du kannst sogar den FileSeparator in Erfahrung bringen (bei Windows der Backslash und bei Unix der Slash).
Einzig das Java Native Interface (JNI) bietet die Möglichkeit, auf native, und damit plattformspezifischen, Funktionen zuzugreifen.

Das mit dem Menüeintrag ist leider immer noch das Problem.
Selbst wenn ich beim Schließen auf das X verweisen kann,
funktioniert das mit dem Sprachenwechsel nicht. Nachdem ich
gestern über 2 Stunden danach krampfhaft gesucht habe, glaub
ich fast dass die Komponente dazu nicht in der Lage ist. (Alle
anderen Programmiersprachen die ich verwendete konnten das)

Hm… ich glaube du verwürfelst da was. Oder ich versteh was nicht richtig…
Der Sprachwechsel ist nicht Aufgabe der Menuleiste. Du könntest genauso gut einen Button damit beauftragen, das würde keinen Unterschied machen.
Den zweiten Teil versteh ich nicht. Was genau hast du versucht, und welche Komponente ist wozu nicht in der lage?

Das mit dem selber Zeichnen der Progressbar und des Diagramms
sind wohl am sinnvollsten. Auch weil man dann in die Details
gehen kann.

Also wie gesagt, die Progressbar musst du auf jeden fall nicht selber malen, das gibts schon.
Wenn man Deteils nicht sehen kann, dann hilft dir aber auch fertiges Balkendiagramm nicht, oder? Also ich seh kein Problem beim zeichnen des Diagramms, zumal das wirklich nicht besonders aufwändig ist.
Aber abgesehen davon hab ich mal grad Google angeschmissen und siehe da: Natürlich gibts was. Z.B. JFreeChart:
http://www.jfree.org/jfreechart/

Vielleicht zeichne ich dann auch gleich noch eine
Baumstruktur. Denn so ein Dialogfenster ist für mein Vorhaben
nicht gerade Benutzerfreundlich.

Wo willst du den Baum denn haben? Es gibt natürlich einen Baum in Swing, den JTree. Ich dachte der wäre nur zur für nen Datei-Auswahldialog gut, und da kann man ihn auch getrost weg lassen. Aber wenn du ihn immer haben willst, könntest du dir nen JTree basteln, der Files Beinhaltet. Ich stell mir das im Moment über ein TreeModel relativ einfach vor (da File ja schon alle Parent- und Children-Getter hat), kann aber sein, dass ich mich täusche.

Wenn die Plattformbedingten Probleme erledigt sind (Datei- und
Ordnerzugriff, Steuerung des Programms) wäre der Rest - also
die Verarbeitung der Informationen - ein Kinderspiel. Denn da
unterscheiden sich die Sprachen wenig.

Jo, vermutlich. Wobei die Verarbeitung aber schätzungsweise den kleinsten Teil der Arbeit ausmachen wird.
Die Programmsteuerung könnte tatsächlich ein wenig Zeit in Anspruch nehmen, wenn du das noch nie gemacht hast.
Aber den Datei-Zugriff finde ich in Java sehr schön gelöst. Wie gesagt, File kann alles was man so mit Files anstellen kann, zumindest mit Informationen über sie. Willst du den Inhalt lesen oder bearbeiten, hilft dir die Klasse nicht mehr weiter. Und ganz mies wirds dann beim kopieren oder verschieben einer Datei, aber das ist ein anderes Thema.

Gruß,
yYy

Ah ok, ich habs jetzt gesehen. NetBeans greift auf Swing und AWT zurück. Wobei Swing viel mehr Komponenten hat, also verwend ich Swing.

Was ich mir immer noch problematisch vorstelle ist die unterschiedliche Ordnerstruktur in Windows, Linux und Mac. Muss man hier für jedes Betriebssystem einen speziellen Zugriff basteln? Gerade weil man doch immer mit einem absoluten Pfad arbeitet.

Und zur Baustelle Menuleiste: In einer JMenuBar kann ich JMenu Einträge mit JMenuItem festlegen. Wenn der JMenu Eintrag nur ein JMenuItem hat, möchte ich aber nicht umständlich zum JMenuItem wechseln sondern direkt die Aktion beim Klick auf das JMenu starten. Im speziellen Fall soll dann die Sprache gewechselt werden.
Sollte dies nicht gehen, schalt ich die Menüleiste komplett ab und verwende einfach einen Button.

Mit den Details beim Diagramm meint ich Feinheiten wie die richtige Plazierung der Zahlenwerte, optische Gestaltung der Diagramme etc. . Ich denk da eine eine Tabelle wo darüber die Häufigkeiten als Säulendiagramme gezeichnet werden.

Die Komponente JTree macht einiges leichter. Ich habe auch schon Ansätze gefunden, wie man damit FileBrowser basteln kann. Mit den Bedenken von mir der Plattformunabhängigkeit. Zur Begründung: Einerseits soll die Ordnerauswahl wieder direkt erfolgen (einfachere Bedienung) und zum anderen soll der Wechsel für verschiedene Ordner schneller vonstatten gehen. Damit kann der Nutzer mal schnell eine Ebene höher gehen (Datensatzumfang erhöhen) oder auch wechseln.

Soweit erstmal die Theorie. Praktisch Zeit investieren werde ich wohl erst ab Mitte nächste Woche. Voher muss noch am Montag eine Statistikprüfung bestanden werden.

Danke und Gruß
DuAK007

Was ich mir immer noch problematisch vorstelle ist die
unterschiedliche Ordnerstruktur in Windows, Linux und Mac.
Muss man hier für jedes Betriebssystem einen speziellen
Zugriff basteln? Gerade weil man doch immer mit einem
absoluten Pfad arbeitet.

Ich denke nicht, ich würde es spontan mal über File.listRoots() probieren.
Absolute Pfade sind auch kein Problem. Problematisch wirds nur, wenn du irgendwas davon hardocdest. D.h. du darfst nirgends in deinem Quellcode einen ausgeschriebenen String im Zusammenhang mit Files haben. (Grob gesagt. Es gibt natürlich Anwendungen, wo du das brauchst, wenn du z.B. nach einem bestimmten Dateinamen suchst.) Und du kannst tatsächlich alles, was du brauchst dynmaisch machen, von den grade angesprochenen Filesystem-roots bis zum bereits erwähnten FileSparator.

Und zur Baustelle Menuleiste: In einer JMenuBar kann ich JMenu
Einträge mit JMenuItem festlegen. Wenn der JMenu Eintrag nur
ein JMenuItem hat, möchte ich aber nicht umständlich zum
JMenuItem wechseln sondern direkt die Aktion beim Klick auf
das JMenu starten. Im speziellen Fall soll dann die Sprache
gewechselt werden.
Sollte dies nicht gehen, schalt ich die Menüleiste komplett ab
und verwende einfach einen Button.

Tja, mal ganz abgesehen davon, dass eine Menüleiste mit nur einem Knopf ein wenig lächerlich aussieht, ist JMenuBar eben auch ein Container und hat damit eine add(Component comp) Methode. Will heißen, du kannst theoretisch nicht nur JMenus auf die Leiste packen, sondern eben auch ein JMenuItem oder einen JButton oder so. Nur stellt er das dann über die ganze Breite der Leiste dar, dem könntest du aber beispielsweise mit setMaximumSize() entgegenwirken.

Mit den Details beim Diagramm meint ich Feinheiten wie die
richtige Plazierung der Zahlenwerte, optische Gestaltung der
Diagramme etc. . Ich denk da eine eine Tabelle wo darüber die
Häufigkeiten als Säulendiagramme gezeichnet werden.

Klar, je besser es aussehen soll, desto aufwendiger wirds. Und bis du selbst was geschrieben hast, das es mit JFreeChart aufnehmen kann, wird schon einige Zeit vergehen (hast du mal die Demo gestartet?). Aber das ist ja das tolle: Du brauchst es nicht, du kannst einfach das fertige nemen.

Die Komponente JTree macht einiges leichter. Ich habe auch
schon Ansätze gefunden, wie man damit FileBrowser basteln
kann. Mit den Bedenken von mir der Plattformunabhängigkeit.
Zur Begründung: Einerseits soll die Ordnerauswahl wieder
direkt erfolgen (einfachere Bedienung) und zum anderen soll
der Wechsel für verschiedene Ordner schneller vonstatten
gehen. Damit kann der Nutzer mal schnell eine Ebene höher
gehen (Datensatzumfang erhöhen) oder auch wechseln.

Du siehst ein Problem in der Selektion eines Astes(/Ordners)? Versteh ich nicht.

Soweit erstmal die Theorie. Praktisch Zeit investieren werde
ich wohl erst ab Mitte nächste Woche. Voher muss noch am
Montag eine Statistikprüfung bestanden werden.

Viel Glück damit und schöne Grüße
yYy

Ich nochmal.
Die Idee mit dem JTree als Filebrowser hat mich irgendwie fasziniert, so dass ich mal grad was geschrieben hab, was in meinen Augen schon relativ brauchbar aussieht. Getestet bei mir auf Ubuntu, kannst es ja mal auf Windows laufen lassen. Das Progrämmchen kann auch Dateien rausfiltern, so dass du nur Ordner bekommst, dazu einfach den Konstruktorübergabeparameter ändern.

Die Klasse hier ist ne Testklasse, sie generiert ein JFrame mit nem JTree drin:

public class Main extends JFrame
{
 public static void main(String args[])
 {
 Main frame = new Main();
 frame.setVisible(true);
 }

 public Main()
 {
 super();
 setDefaultCloseOperation(JFrame.EXIT\_ON\_CLOSE);

 final JScrollPane scrollPane = new JScrollPane();
 getContentPane().add(scrollPane, BorderLayout.CENTER);

 JTree tree = new JTree(new FileBrowserTreeModel(null, false));
 tree.setRootVisible(false);
 scrollPane.setViewportView(tree);

// pack();
 setSize(300, 500);
 setLocationRelativeTo(null);
 }
}

Interessant wirds hier, die Klass hab ich dem Tree als Model geschrieben:

public class FileBrowserTreeModel implements TreeModel
{
 private File root;
 private static final Object dummyRoot = new Object();
 private boolean hasRoot;
 private boolean showDirectoriesOnly;
 private static final FileFilter directoriesOnlyFilter = new FileFilter()
 {
 @Override
 public boolean accept(File pathname)
 {
 return pathname.isDirectory();
 }
 };
 private static final Comparator directoriesFirstComparator = new Comparator()
 {
 @Override
 public int compare(File f1, File f2)
 {
 //nullFilter
 if (f1 == f2)
 return 0;
 if (f1 == null)
 return 1;
 if (f2 == null)
 return -1;
 //gleiche Dateien sind gleich
 if (f1.equals(f2))
 return 0;
 //und ordner kommen vor dateien
 if (f1.isDirectory() ^ f2.isDirectory())
 {
 if (f1.isDirectory())
 return -1;
 else
 return 1;
 }
 else
 return f1.compareTo(f2);
 }
 };

 public FileBrowserTreeModel(File root, boolean showDirectoriesOnly)
 {
 if (root == null)
 hasRoot = false;
 else
 {
 hasRoot = true;
 if (root.isDirectory())
 this.root = root;
 else
 this.root = root.getParentFile();
 }

 this.showDirectoriesOnly = showDirectoriesOnly;
 }

 @Override
 public Object getChild(Object parent, int index)
 {
 File[] ret;
 if (!hasRoot && parent == dummyRoot)
 ret = File.listRoots();
 else if (!(parent instanceof File))
 return null;
 else if (showDirectoriesOnly)
 ret = ((File)parent).listFiles(directoriesOnlyFilter);
 else
 ret = ((File)parent).listFiles();
 Arrays.sort(ret, directoriesFirstComparator);
 return ret[index];
 }

 @Override
 public int getChildCount(Object parent)
 {
 if (!hasRoot && parent == dummyRoot)
 return File.listRoots().length;
 if (!(parent instanceof File))
 return 0;
 if (showDirectoriesOnly)
 return ((File)parent).listFiles(directoriesOnlyFilter).length;
 return ((File)parent).listFiles().length;
 }

 @Override
 public int getIndexOfChild(Object parent, Object child)
 {
 File[] ret;
 if (!hasRoot && parent == dummyRoot)
 ret = File.listRoots();
 else if (!(parent instanceof File))
 return 0;
 else if (showDirectoriesOnly)
 ret = ((File)parent).listFiles(directoriesOnlyFilter);
 else
 ret = ((File)parent).listFiles();
 Arrays.sort(ret, directoriesFirstComparator);
 return Arrays.binarySearch(ret, child);
 }

 @Override
 public Object getRoot()
 {
 if (hasRoot)
 return root;
 return dummyRoot;
 }

 @Override
 public boolean isLeaf(Object node)
 {
 if (!hasRoot && node == dummyRoot)
 return false;
 if (!(node instanceof File))
 return true;
 return ((File)node).isFile();
 }



 //für den Test nicht gebraucht

 @Override
 public void addTreeModelListener(TreeModelListener l)
 {}

 @Override
 public void removeTreeModelListener(TreeModelListener l)
 {}

 @Override
 public void valueForPathChanged(TreePath path, Object newValue)
 {}
}