Die Entwicklungsumgebung intelliJ IDEA hat einen sehr guten GUI-Builder und -Editor, aber es gibt eine Sache, bei der intelliJ grottenschlecht arbeitet, und das ist die Erstellung eines Menüs. Ihr werdet Euch bei den diversen Beispielen zur JTextPane sicherlich gefragt haben: „warum verwendet er kein Menü ?“ – hier ist die Antwort.
Ich habe sehr viele Webseiten durchsucht und ausprobiert, die nachstehende Lösung ist die einzig funktionierende Variante. Üblicherweise wird das Menü ja innerhalb der Klasse programmiert, in der das Menü auch genutzt werden soll, aber das funktioniert leider nicht.
Die Lösung besteht darin, dass ich eine „Starterklasse“ („Main.java“) der „TextPane.java“ vorschalte und das Menü darin händisch aufbaue. Ebenso werden auch die Action Listener der einzelnen Menüpunkte innerhalb der Starterklasse erstellt. Dann wird das Menü der ContentPane hinzugefügt, allerdings mit dem Kniff, dass ich den Namen des Ziel-Panels innerhalb der TextPane-Klasse abfrage und der Starterklasse zur Verfügung stelle:
1 |
public JPanel getPanel() { return panelMain;} |
1 |
frame.setContentPane(form.getPanel()); |
Hierdurch kann ich die komplette Funktionalität des Menüs nutzen und verwenden:
Nun folgen die Quellcodes, wie immer benötigt Ihr intelliJ zum Nachbau:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
/* * Herkunft/Origin: http://java-crypto.bplaced.net/ * Programmierer/Programmer: Michael Fehr * Copyright/Copyright: frei verwendbares Programm (Public Domain) * Copyright: This is free and unencumbered software released into the public domain. * Lizenttext/Licence: <http://unlicense.org> * getestet mit/tested with: Java Runtime Environment 8 Update 191 x64 * getestet mit/tested with: Java Runtime Environment 11.0.4 x64 * Datum/Date (dd.mm.jjjj): 12.02.2020 * Funktion: TextPane Menue * Function: TextPane Menue * * Sicherheitshinweis/Security notice * Die Programmroutinen dienen nur der Darstellung und haben keinen Anspruch auf eine korrekte Funktion, * insbesondere mit Blick auf die Sicherheit ! * Prüfen Sie die Sicherheit bevor das Programm in der echten Welt eingesetzt wird. * The program routines just show the function but please be aware of the security part - * check yourself before using in the real world ! */ import javax.swing.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ResourceBundle; public class Main { public static ResourceBundle resourceBundle; public static void main(String[] args) { JMenuBar menuBar; JMenu menuFile, menuEdit; JMenuItem menuItemExit, menuItemLoad, menuItemSave, menuItemCopy, menuItemPaste; menuBar = new JMenuBar(); menuFile = new JMenu("File"); menuBar.add(menuFile); menuItemLoad = new JMenuItem("Load"); menuFile.add(menuItemLoad); menuItemSave = new JMenuItem("Save"); menuFile.add(menuItemSave); menuItemExit = new JMenuItem("Exit"); menuFile.add(menuItemExit); menuEdit = new JMenu("Edit"); menuBar.add(menuEdit); menuItemCopy = new JMenuItem("Copy"); menuEdit.add(menuItemCopy); menuItemPaste = new JMenuItem("Paste"); menuEdit.add(menuItemPaste); TextPane form = new TextPane(); JFrame frame = new JFrame("TextPane Menü"); frame.setContentPane(form.getPanel()); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // insert of the menue frame.setJMenuBar(menuBar); frame.pack(); frame.setSize(500, 300); frame.setVisible(true); menuItemLoad.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { form.loadRtf("textpane_rtf.rtf"); } }); menuItemSave.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { form.saveRtf("textpane_rtf.rtf"); } }); menuItemExit.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { System.exit(0); } }); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
/* * Herkunft/Origin: http://java-crypto.bplaced.net/ * Programmierer/Programmer: Michael Fehr * Copyright/Copyright: frei verwendbares Programm (Public Domain) * Copyright: This is free and unencumbered software released into the public domain. * Lizenttext/Licence: <http://unlicense.org> * getestet mit/tested with: Java Runtime Environment 8 Update 191 x64 * getestet mit/tested with: Java Runtime Environment 11.0.4 x64 * Datum/Date (dd.mm.jjjj): 12.02.2020 * Funktion: TextPane Menue * Function: TextPane Menue * * Sicherheitshinweis/Security notice * Die Programmroutinen dienen nur der Darstellung und haben keinen Anspruch auf eine korrekte Funktion, * insbesondere mit Blick auf die Sicherheit ! * Prüfen Sie die Sicherheit bevor das Programm in der echten Welt eingesetzt wird. * The program routines just show the function but please be aware of the security part - * check yourself before using in the real world ! */ import javax.swing.*; import javax.swing.text.BadLocationException; import javax.swing.text.DefaultStyledDocument; import javax.swing.text.StyleContext; import javax.swing.text.StyledDocument; import javax.swing.text.rtf.RTFEditorKit; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.io.*; public class TextPane { private JPanel panelMain; private JPanel panelButtons; private JButton buttonLoad; private JScrollPane scrollPane; private JTextPane textPane; private JButton buttonSave; public TextPane() { textPane.setContentType("text/rtf"); textPane.setEditorKit(new RTFEditorKit()); buttonLoad.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { loadRtf("textpane_rtf.rtf"); } }); buttonSave.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent actionEvent) { saveRtf("textpane_rtf.rtf"); } }); } public JPanel getPanel() { return panelMain; } public void loadRtf(String filename){ RTFEditorKit RTF_KIT = new RTFEditorKit(); textPane.setContentType("text/rtf"); InputStream inputStream; try { inputStream = new FileInputStream(filename); final DefaultStyledDocument styledDocument = new DefaultStyledDocument(new StyleContext()); RTF_KIT.read(inputStream, styledDocument, 0); textPane.setDocument(styledDocument); // delete added last line String content = textPane.getDocument().getText(0, textPane.getDocument().getLength()); int lastLineBreak = content.lastIndexOf('\n'); textPane.getDocument().remove(lastLineBreak, textPane.getDocument().getLength() - lastLineBreak); } catch (IOException | BadLocationException e) { e.printStackTrace(); } textPane.requestFocus(); } public void saveRtf(String filename){ try { FileOutputStream fos = new FileOutputStream(filename); RTFEditorKit kit = (RTFEditorKit) textPane.getEditorKit(); StyledDocument doc = textPane.getStyledDocument(); int len = doc.getLength(); kit.write(fos, doc, 0, len-2); fos.close(); } catch (IOException | BadLocationException e) { e.printStackTrace(); } textPane.requestFocus(); } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
<?xml version="1.0" encoding="UTF-8" ?> - <form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="TextPane"> - <grid id="27dc6" binding="panelMain" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> <margin top="10" left="10" bottom="10" right="10" /> - <constraints> <xy x="20" y="20" width="500" height="400" /> </constraints> <properties /> <border type="none" /> - <children> - <grid id="69623" binding="panelButtons" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1"> <margin top="0" left="0" bottom="0" right="0" /> - <constraints> <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false" /> </constraints> <properties /> <border type="none" /> - <children> - <component id="b1559" class="javax.swing.JButton" binding="buttonLoad"> - <constraints> <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false" /> </constraints> - <properties> <text value="load" /> </properties> </component> - <component id="1e556" class="javax.swing.JButton" binding="buttonSave"> - <constraints> <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false" /> </constraints> - <properties> <text value="save" /> </properties> </component> </children> </grid> - <scrollpane id="5bf0e" binding="scrollPane"> - <constraints> <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false" /> </constraints> <properties /> <border type="none" /> - <children> - <component id="100bc" class="javax.swing.JTextPane" binding="textPane"> <constraints /> <properties /> </component> </children> </scrollpane> </children> </grid> </form> |
Alle Quellcodes zur JTextPane findet Ihr zum Download in meinem Github-Repository, welches Ihr über diesen Link erreicht: https://github.com/java-crypto/JTextPane. Alle Programme sind unter Java 11 lauffähig (vermutlich auch unter Java 8) und wurden mit intelliJ IDEA entwickelt, welches für das eigene „Spielen“ notwendig ist.
Die Lizenz zum obigen Beispiel findet Ihr auf der eigenen Lizenz-Seite.
Letzte Bearbeitung: 12.02.2020