Ich würde gerne einen mathematischen Texteditor schreiben, mit dem es möglich ist mathematische und logische Formeln zu schreiben und das möglichst auf eine einfache Art und Weise.
Wichtig ist mir hierbei, dass Buchstaben und Formeln hoch und tiefgestellt werden können, ausserdem wäre es praktisch, wenn griechische Buchstaben unterstützt werden sowie die gängigen Zeichenformeln wie Sigma (Summenformel), kanonsche Summenformel, Integrale, etc.
Wie würdet ihr da am besten vorgehen? Also welches Pane würdet ihr da empfehlen, etwa Canvas?
Oder wäre Javascript eine Lösung, so dass ich quasi den Texteditor als Webscript in einer Webview anzeige lasse?
Hintergrund hierfür ist, dass mir OpenOffice und LibreOffice nicht so gefallen wenn es darum geht, komplizierte Brüche etc zu schreiben.
Wenn das Programm fertig ist, würde ich es gerne erweitern um algebraische Umformungen zu machen, DGLs zu lösen, etc.
Einfach um mich wieder etwas mehr mit der Mathematik und gleichzeitig mit Java zu beschäftigen.
Da ich auch gerade Python lerne.. seht ihr eine Möglichkeit Python sinnvoll einzusetzen? Python hat ja tolle packages wie numpy und scypy.
Leider nur Python 2.7 und das obwohl das bald deprecated/EOL wird...
(Für Tutorials zur Integration mal googlen. Ist im Wesentlichen ein Python-Interpreter auf der JVM, und vermutlich durch die ScriptEngine der JVM angebunden. Hab sie selbst - trotz Interesse - nie verwendet.)
Für die Formeln wird es etwas schwerer: Ich habe mal nach "javafx formula" gegooglet und bin dabei u.a. auf folgende Links gestossen
Du kannst/musst also deine Formeln in einer Beschreibung wie etwa LaTeX machen und dann durch die Controls in den Links in deiner Anwendung rendern lassen.
Ja so weit bin ich auch mittlerweile auch schon.
Habe bisher alles in JavaFX realisiert ohne Jython (da es mit Python 2.x doch etwas umständlicher ist als ich dachte).
Problem sind nur die JavaFX Controls.. weshalb ich wohl alles in Python machen werden.
Denn: LaTeX-, ich nenne ich sie mal Formulare, müssen als Bilder gerendered werden und JavaFX unterstützt bisher (soweit ich weiß) kein Textfeld, das Bilder und Texte akzeptiert.
Mit TextFlow habe ich es schon probiert und bekomme auch die passenden mathematischen Ausdrücke mittels LaTeX-Parser als Image, welches ich in TextFlow einfüge.
Problem: Das Ganze soll ja ein Editor werden und ich habe bisher noch keine Möglichkeit gefunden, während der Laufzeit in ein Textflow zu schreiben, da ja alles Text und nicht als String dort gespeichert wird und ein Textflow nicht direkt editierbar ist. So müsste ich alles über ein Eingabefeld machen, was mMn. aber Humbug ist (für die Formeln wäre das ok...).
Das Problem ist also kurz zusammengefasst: Mir fehlt ein Control, dass wie eine TextArea ist aber zusätzlich noch Bilder akzeptiert (quasi eine Kombi aus TextArea und TextFlow).
Pythons TKinter TextBox unterstützt das Anzeigen von Text und Bild und funktioniert so ähnlich wie eine JavaFX TextArea.
PS: Habe auch schon den Weg über WebView + JavaScript + HTML versucht, doch auch dort habe ich das Problem, dass die TextArea kein Bild einfügen kann (zumindest hat es bei mir nicht geklappt).
Verstehe die Problematik. Ich würde in dem Fall trotzdem einen Textflow nehmen. Die fertigen Ausdrücke (nach Eingabetaste oder so?) anzeigen. Und die Eingabe selbst: Ich würde einfach als letzes Element im TextFlow ein TextField einfügen. Alternativ ginge auch ein FlowPane, dann wird immer alles ordentlich zentriert dargestellt (das ist bei TextFlow einfach etwas kniffelig). Und ich würde den Container (FlowPane oder TextFlow) im CSS so gestalten, dass es wie eine Text-Area aussieht und dass TextField ohne Rahmen (damit man nicht sieht, dass du schummelst ).
Ich kenn mich nicht mehr so genau mit der LaTeX-Syntax aus (Open-/LibreOffice hat(te) ja IMHO ein vereinfachtes Derivat davon in Verwendung), aber wenn du mir ein paar Formeln gibst, würde ich vielleicht damit mal ein kleines Beispiel machen und hier posten (du kannst ja dein Python-Programm weitermachen).
Also bei OpenOffice/LibreOffice finde ich es einfach sehr unpraktisch, dass man immer diesen Mathe-Editor aufmachen muss und er sich immer schließt, sobald man eine Formel eingegeben hat.
Deswegen würde ich gerne diesen Workflow beschleunigen.
So in etwa dachte ich mir das auch mit dem TextField einbinden nach jeder Space-Taste, aber das Alignment-Management wäre mir dann einfach etwas zu heftig und kompliziert bei dem TextFlow.. Mit CSS kenne ich mich noch nicht so gut aus, vor allem wenn es darum geht Controls stark abzuändern.
Bisher habe ich immer nur Textfarben oder ähnliches verändert aber nie die Form. Denke da kann ich mich aber auch leicht einarbeiten (falls es gut dokumentiert ist).
Tiefgestelle Ausdrücke: "_" -> x_0 ergibt ein x mit einer tiefgestellten 0. Allgemeine Syntax lautet _{} wobei man in der geschweiften Klammer mehrere Ausdrücke angeben kann
Hochgestellte Ausdrücke: ^{} -> x^0 ergibt ein x mit einer hochgestellten 0.
Integral: \int_{}^{}: ergibt ein Integral mit einer von (underscore) bis (hochgestellt) Grenze
Summe: \sum_{}^{}: ergibt das Summenzeichen mit den Grenzen, Beispiel: \sum_{i=0}^{n}
Brüche: \frac{}{}: erster Ausdruck steht für Zähler, zweiter für Nenner, Beispiel: \frac{\cos{\theta}}{\sin{\alpha}}
Griechische Buchstaben: einfach ein vorangestelltes "\" und den Namen, Beispiel: \alpha, \beta\, \delta, \Delta, \theta, ...
Da gibt's noch was zu beachten:
Es gibt sogenannte Inline und Display Methoden:
Inline-Methoden werden benutzt, wenn man einen mathematischen Ausdruck innerhalb eines Textes anzeigen will, während der Display-Modus quasi als Bild dargestellt wird, das in eine eigene Zeile geschrieben wird und auch eine ganze Zeile beansprucht.
Für Inline umschließt man den gesamten Ausdruck typischerweise mit: $ausdruck$
Für Display kann man entweder "$$ausdruck$$" oder "\[ausdruck\]" verwenden.
Im Folgenden zeige ich dir mal bisher, was ich so habe:
publicclassMyEditorViewextendsVBox{privateMainPresenter presenter;privateImageView selectedImageView;publicMyEditorView(){}publicvoidinit(){MyTextFlow textFlow =newMyTextFlow();
textFlow.setLineSpacing(10);
textFlow.setPadding(newInsets(10));TextField textField =newTextField();Button button =newButton("Send");
button.setPrefWidth(70);getChildren().addAll(textFlow,newHBox(textField, button));setVgrow(textFlow,Priority.ALWAYS);// Textfield re-sizes according to VBox
textField.prefWidthProperty().bind(this.widthProperty().subtract(button.prefWidthProperty()));// On Enter press
textField.setOnKeyPressed(e ->{if(e.getCode()==KeyCode.ENTER){
button.fire();}});
button.setOnAction(e ->{if(selectedImageView ==null){String frml = textField.getText();ImageView iv = presenter.createImageViewFromFormula(frml);if(iv !=null){
textFlow.getChildren().add(iv);
selectedImageView = iv;}else{
textField.setText(textField.getText()+" could not be parsed!");}}else{if(textField.getText().isEmpty()){
presenter.removeFormula(selectedImageView);}else{
presenter.updateFormulaModel(selectedImageView, textField.getText());ImageView tmpIv = presenter.createImageViewFromFormula(textField.getText());if(tmpIv !=null){Image img = tmpIv.getImage();
selectedImageView.setImage(img);}else{}}}});String formula ="\\sum_{i=0}^n i^2 = \\frac{(n^2+n)(2n+1)}{6}";ImageView iv = presenter.createImageViewFromFormula(formula);
textFlow.getChildren().add(iv);
presenter.updateFormulaModel(iv, formula);
iv.setOnMouseClicked(e ->{String frml = presenter.getFormulaFromSelectedImageView(iv);if((frml !=null)&&!frml.isEmpty()){
textField.setText(frml);
selectedImageView = iv;}});}publicvoidsetPresenter(MainPresenter present){this.presenter = present;}}
Java:
importjava.awt.image.BufferedImage;importorg.scilab.forge.jlatexmath.TeXConstants;importorg.scilab.forge.jlatexmath.TeXFormula;importjavafx.embed.swing.SwingFXUtils;importjavafx.scene.image.Image;importjavafx.scene.image.ImageView;publicclassTeXUtil{publicstaticbooleanisParsable(String formula){try{TeXFormula tex =newTeXFormula(formula);
java.awt.Image awtImage = tex.createBufferedImage(TeXConstants.STYLE_DISPLAY,12, java.awt.Color.BLACK,null);SwingFXUtils.toFXImage((BufferedImage) awtImage,null);}catch(Exception e){System.out.println("Could not create TeXFormula: "+ e);returnfalse;}returntrue;}publicstaticImageViewparseFormula(String formula){ImageView iv =null;try{TeXFormula tex =newTeXFormula(formula);
java.awt.Image awtImage = tex.createBufferedImage(TeXConstants.STYLE_DISPLAY,12, java.awt.Color.BLACK,null);Image fxImage =SwingFXUtils.toFXImage((BufferedImage) awtImage,null);
iv =newImageView(fxImage);// As we create a new object which doesn't exist before, we need to// add// it directly to call it afterwards.}catch(Exception e){System.out.println("Could not create TeXFormula: "+ e);}return iv;}}
Java:
import home.TextForms.util.TeXUtil;importjavafx.scene.text.Text;importjavafx.scene.text.TextFlow;publicclassMyTextFlowextendsTextFlow{publicMyTextFlow(){super();}publicvoidsetText(String text){String[] split = text.split("\\s+");getChildren().clear();Text t =newText();StringBuilder sb =newStringBuilder();for(String str : split){if(TeXUtil.isParsable(str)){
t.setText(sb.toString());getChildren().add(t);
t =newText();// reset StringBuilder
sb.setLength(0);// set length of buffer to 0
sb.trimToSize();}else{
sb.append(str);
sb.append(" ");}}}}
Das Projekt ist ein Maven Projekt und meine POM.XML hat folgende Dependencies für die LaTeX-Lib:
Genutzt wird Java 8.
Die eigene TextFlow ist unfertig. Hier wollte ich die Idee mit dem "splitten" des Textes realisieren, aber hab nicht viel gemacht, weil mir relativ früh klar wurde, dass mein Vorhaben so nicht funktioniert.
Du kannst dir gerne nehmen was du brauchst.
Falls du alle Klassen importiert und das Programm startest, kannst du mal auf die Gleichung linksklicken, dann erscheint im TextFeld die LaTeX-Formel dafür und kannst etwas damit rumspielen, wird automatisch nach einem Enter-Klick oder Button-Klick aktualisiert.
Hoffe ich hab an alles gedacht
Edit: Das Projekt ist mit Absicht nach dem MVP-Prinzip gestaltet, damit ich für die kommende Klausur besser vorbereitet bin (unser Dozent gibt das MVP-Prinzip vor). Normalerweise arbeite ich mit FXML und nach dem MVC-Prinzip. Hoffe dir macht das nichts aus.
Mir macht das nichts aus. Nur ich werde es wieder auf MVC umstellen, weil ich MVP etwas umständlich finde. (Siehe Verlinke Model auf Presenter, verlinke Presenter auf Model - und mach noch das Init auf dem View alleine (um so was kümmert sich doch der FXMLLoader )).
Ausserdem mag ich es nicht so sehr, die UI in Code zu schreiben.
Ja das ist auch meine bevorzugte Art und Weise aber naja
Richtig hässlich wird es wenn man mehrere Views hat. Ein reines Presenter - View- Model Gewurstel
Eben. Dann entzieht sich mir auch der Sinn des ganzen. Nur um MVP zu machen, muss ich mir doch nicht so einen sch*** antun. Schon mal JavaFXPorts versucht eine App zu schreiben? Sie geben auch gern MVP vor, was ich auch dort nicht leiden kann...
Hat dein Dozent schon überhaupt mal mit JavaFX gearbeitet? Klingt nach einem, der bei Swing geblieben ist.
Wie auch immer: Das Gute ist ja - auch bei JavaFXPorts - dass man am Ende ja zu nichts gezwungen wird. Und auch, wenn du deinen Dozenten hinter dich gebracht hast, wird es so sein. Am Ende macht man das, was einem am Besten liegt. Es ist auf jeden Fall mal gut, dass du dadurch alles mögliche probieren konntest. In meiner Uni wurde man zu nichts gezwungen - solche Programmier-Paradigmen standen nur am Rande auf dem Programm.
Ja sicher, wir behandeln nur Javafx. Habe noch nie mit anderen Technologien gearbeitet (also weder Swing, AWT oder SWT).
Wir kriegen ein Prinzip für die Klausur vorgeschrieben, selbstverständlich MVP, und es gibt massig Punktabzüge wenn wir es nicht mit MVP machen
Auf der Arbeit programmiere ich auch mit MAC, gefällt mir halt am besten.
Das mit dem "Man macht was einem am besten liegt" ist eine gute Sache. Deswegen will ich auch so viel lernen wie es geht
Sag mal: um mein Vorhaben zu realisieren mit dem Textflow; wäre es generell möglich ein Textflow so zu erweitern, dass man in das Control klicken kann und reinschreiben kann wie bei einem Textarea (ohne Verwendung anderer Controls, also ohne die Schummelei)? Ich würde mal gerne wissen wo die Grenzen liegen, Controls zu erweitern.
Nein, das dürfte nicht gehen. Immerhin ist ein TextFlow am Ende nichts anderes als ein Layout (erbt von Pane) und kein Control. Sicher: Em Ende erben alle von Node, aber das hat damit eher weniger zu tun.
Also: Entweder du schreibst dein eigenes Control von anfang an, inkl. Layouting und Text-Input, oder du kombinierst halt bestehende Sachen, was am Ende a) meist genügt und b) am schnellsten geht.
Ausserdem muss man sich sonst halt mit den JavaFX Skins beschäftigen - das war mir meist zu mühsam, daher habe ich mich bisher auf die Variante des Kombinierens verlassen.
Ich muss noch mal folgendes anmerken: Ich habe mal etwas mit der SciLab-Bibliothek herumgespielt und es funktioniert erwartungsgemäß.
Aber: Was genau ist das Ziel? Wie soll es am Ende aussehen?
Ich bin an dem Punkt, an dem ich einen Flow nicht mehr so toll finde: Zum einen muss man die Bilder eigentlich immer translaten (etwas nach unten bringen), damit es gut aussieht. Zum anderen ist ein Zeilenumbruch etwas aufwändiger:
Ich dachte erst, ein FlowPane wäre toll (die Bilder werden schön pro Zeile vertikal zentriert ausgelegt), aber Zeilenumbruch? Pustekuchen.
TextFlow: Zeilenumbruch möglich, aber dafür sind die items schlecht ausgelegt: text und input zentrieren sich, die Bilder aber nicht.
Ich überlege gerade, ob man einen ListView verwenden könnte: Eine Zeile = ein Listeneintrag.
Ansonsten würde ich wohl fast folgendes Vorgehen bevorzugen:
ScrollPane mit VBox, Und ein VBox-Kind = eine Formel. (Alternativ stat ScrollPane und VBox auch ListView).
Speziell zum ListView könnte mir hier ein Master-Detail-Modell vorstellen: Links die Liste mit den Einträgen und recht - nachdem sie angeklickt wurden - eine TextArea. Alternativ statt Detail-Bereich ginge auch ein Popup/Dialog für den Listeneintrag. Könnte mir hier einige Sachen vorstellen, aber als InlineEditor bin ich gerade mit den Styling auch etwas überfragt, solange wie wir nicht auf ein eigenes Pane (wo man sich eben um das Layouting selbst kümmern muss) zurückgreifen.
#edit: wenn du magst, kann ich das ja mal das, was ich hab, nach GitHub pushen und du schaust drüber - eventuell als "Collaborator" oder Forken und mit Pull Request updaten.
Ok ich verstehe die Problematik.. hab gerade etwas wenig Luft zum schreiben. Daher würde ich sagen ich melde mich morgen oder übermorgen. Nur damit du nicht denkst ich würde jetzt nicht mehr schreiben
Aber:
Java FX ist ja schon mächtig. Aber dass es nicht mal eine Textarea gibt, die Bilder akzeptiert könnte doch alles so einfach sein.
Was ist mein Ziel: wenn man es genau nimmt quasi ein LaTeX-Editor, der, wenn der User will, mathematische Formeln (in latex geschrieben) direkt umwandelt und anschaulich darstellt. Da es derzeit etwas schnell gehen muss, verwende ich Texmaker (ein Latex Editor) um Zusammenfassungen für Module wie Angewandte Mathematik, Physik, Theoretische Informatik, etc zu schreiben.
Letzten Endes soll es ein Texteditor werden, der gängige Funktionen wie Zentrieren, dick/kursiv schreiben, etc anbietet wobei das Augenmerk auf das Schreiben von mathematischen Ausdrücken liegt, da die oft gebraucht werden.
Was ich mir auch überlegt habe:
Wie wäre es, wenn ich eigene Controls pro mathematischen Ausdruck schreibe? Bspw 4 HBoxes die jeweils ein TextField enthalten für das Summenzeichen. Eins für das zeigen an sich, eins für die obere, eins für die untere Grenze und eins für den nachfolgenden Ausdruck?
Gern kannst du auch mal das was du hast auf github stellen
Edit: wobei bei meinem Vorschlag auch das Handling des Layouts wieder fragen aufwirft. Kann man dazu nicht "einfach" die HBoxes relativ über die BoundsProperty abhängig von der (später gewählten) Schriftgröße zueinander setzen? Sorgen würde mir hier ganz klar die Performance machen und das würde auch den Rahmen des RAMs sprengen für einen einfachen Texteditor denke ich mal, wenn in dem Pane extrem viele Nodes wären. Komme mir gerade vor als ob ich versuche Tetris zu spielen
Ich versuche mal mit deinen Vorschlägen etwas rumzuspielen und gucke mal wie weit ich komme bzw wie weit du gekommen bist. Ich danke dir jetzt schon für deine mühen
Wirklich viel mach ich nicht, aber ab und an ist mir etwas Wert es ausgelagert zu sichern (meine alten Repos sind z.T. eher nur noch antiquirte Stücke teils hässlichen Codes!).
Grüsse,
Daniel
PS: Um einen vollen Editor zu machen, muss man aber weiter weg schauen. Da reicht jlatexmath nicht mehr. Vielleicht snuggletex?