{"id":1335,"date":"2012-05-27T11:02:17","date_gmt":"2012-05-27T09:02:17","guid":{"rendered":"http:\/\/www.tutego.de\/blog\/javainsel\/?p=1335"},"modified":"2012-05-31T23:26:31","modified_gmt":"2012-05-31T21:26:31","slug":"inselraus-swingauswahlmen-mit-separator","status":"publish","type":"post","link":"https:\/\/www.tutego.de\/blog\/javainsel\/2012\/05\/inselraus-swingauswahlmen-mit-separator\/","title":{"rendered":"Inselraus: Swing\/Auswahlmen&uuml; mit Separator"},"content":{"rendered":"<p>Standardm\u00e4\u00dfig unterst\u00fctzt die JList und auch JComboBox keine Separatoren, doch die Unterteilung in Segmente ist in der Praxis sehr n\u00fctzlich. Microsoft Word und PowerPoint benutzen sie zum Beispiel, um die zuletzt vom Benutzer ausgew\u00e4hlten Zeichens\u00e4tze prominent oben in der Liste zu haben (Excel dagegen tut dies nicht).<\/p>\n<p><a href=\"http:\/\/openbook.galileocomputing.de\/java7\/bilder\/10_043-wordauswahlmenues.png\"><img decoding=\"async\" src=\"http:\/\/openbook.galileocomputing.de\/java7\/bilderklein\/klein10_043-wordauswahlmenues.png\" alt=\"Abbildung\" border=\"1\" \/><\/a><\/p>\n<p><strong>Abbildung 9.42: <\/strong>Separator in Words Zeichensatzauswahlliste<\/p>\n<p>Wir wollen diese M\u00f6glichkeit nachbilden und dabei noch einiges \u00fcber Modelle und Renderer lernen.<\/p>\n<p><a href=\"http:\/\/openbook.galileocomputing.de\/java7\/bilder\/10_044-jcomboboxmitsepa.png\"><img decoding=\"async\" src=\"http:\/\/openbook.galileocomputing.de\/java7\/bilderklein\/klein10_044-jcomboboxmitsepa.png\" alt=\"Abbildung\" border=\"1\" \/><\/a><\/p>\n<p><strong>Abbildung 9.43: <\/strong>Eine eigene Variante mit JSeparator in JComboBox<\/p>\n<p>Bei der Umsetzung gibt es unterschiedliche Varianten, die sich au\u00dfer in der technischen Implementierung darin unterscheiden, ob das Modell eine Markierung f\u00fcr den Separator enth\u00e4lt oder nicht. Wir stellen beide Ans\u00e4tze vor und beginnen mit der ersten Variante, also damit, einem Zellen-Renderer Positionen mitzugeben, die sagen, wo ein Trennstrich zu zeichnen ist.<\/p>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><span style=\"color: #0000ff;\">package<\/span> com.tutego.insel.ui.list;<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><span style=\"color: #0000ff;\">import<\/span> javax.swing.*;<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><span style=\"color: #0000ff;\">public<\/span> <span style=\"color: #0000ff;\">class<\/span> JComboBoxWithSeparator1 {<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  <span style=\"color: #0000ff;\">public<\/span> <span style=\"color: #0000ff;\">static<\/span> <span style=\"color: #0000ff;\">void<\/span> main( String[] args ) <span style=\"color: #0000ff;\">throws<\/span> Exception {<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">    UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() );<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">    JFrame frame = <span style=\"color: #0000ff;\">new<\/span> JFrame();<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">    frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">    String[] items = { \"<span style=\"color: #8b0000;\">Cambria<\/span>\", \"<span style=\"color: #8b0000;\">Arial<\/span>\", \"<span style=\"color: #8b0000;\">Verdana<\/span>\", \"<span style=\"color: #8b0000;\">Times<\/span>\" };<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">    JComboBox&lt;String&gt; comboBox = <span style=\"color: #0000ff;\">new<\/span> JComboBox&lt;&gt;( items );<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">    ListCellRenderer&lt;String&gt; renderer = <span style=\"color: #0000ff;\">new<\/span> SeparatorAwareListCellRenderer1&lt;&gt;(<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">                                          comboBox.getRenderer(), 0 );<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">    comboBox.setRenderer( renderer );<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">    frame.add( comboBox );<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">    frame.pack();<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">    frame.setVisible( <span style=\"color: #0000ff;\">true<\/span> );<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  }<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">}<\/pre>\n<p>Die eigene Klasse SeparatorAwareListCellRenderer1 ist ein ListCellRenderer, den die JComboBox zur Darstellung der Komponenten nutzt. Im Konstruktor des Renderers geben wir den Original-Renderer mit \u2013 es kann ein bestimmter Renderer schon vorinstalliert sein, den wollen wir dekorieren \u2013 sowie eine variable Argumentliste von Positionen. Das Beispiel \u00fcbergibt nur 0, da nach dem ersten Element (Index = 0) ein Trennzeichen zu setzen sein soll, sodass Cambria und Arial abgetrennt sind.<\/p>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><span style=\"color: #0000ff;\">package<\/span> com.tutego.insel.ui.list;<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><span style=\"color: #0000ff;\">import<\/span> java.awt.*;<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><span style=\"color: #0000ff;\">import<\/span> java.util.Arrays;<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><span style=\"color: #0000ff;\">import<\/span> javax.swing.*;<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><span style=\"color: #0000ff;\">public<\/span> <span style=\"color: #0000ff;\">class<\/span> SeparatorAwareListCellRenderer1&lt;E&gt; <span style=\"color: #0000ff;\">implements<\/span> ListCellRenderer&lt;E&gt;<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">{<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  <span style=\"color: #0000ff;\">private<\/span> <span style=\"color: #0000ff;\">final<\/span> ListCellRenderer&lt;? <span style=\"color: #0000ff;\">super<\/span> E&gt; <span style=\"color: #0000ff;\">delegate<\/span>;<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  <span style=\"color: #0000ff;\">private<\/span> <span style=\"color: #0000ff;\">final<\/span> <span style=\"color: #0000ff;\">int<\/span>[] indexes;<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  <span style=\"color: #0000ff;\">private<\/span> <span style=\"color: #0000ff;\">final<\/span> JPanel panel = <span style=\"color: #0000ff;\">new<\/span> JPanel( <span style=\"color: #0000ff;\">new<\/span> BorderLayout() );<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  <span style=\"color: #0000ff;\">public<\/span> SeparatorAwareListCellRenderer1( ListCellRenderer&lt;? <span style=\"color: #0000ff;\">super<\/span> E&gt; <span style=\"color: #0000ff;\">delegate<\/span>,<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">                                          <span style=\"color: #0000ff;\">int<\/span>... indexes )<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  {<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">    Arrays.sort( indexes );<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">    <span style=\"color: #0000ff;\">this<\/span>.<span style=\"color: #0000ff;\">delegate<\/span> = <span style=\"color: #0000ff;\">delegate<\/span>;<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">    <span style=\"color: #0000ff;\">this<\/span>.indexes  = indexes;<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  }<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  @Override<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  <span style=\"color: #0000ff;\">public<\/span> Component getListCellRendererComponent( JList&lt;? extends E&gt; list, E value,<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">                                                 <span style=\"color: #0000ff;\">int<\/span> index, <span style=\"color: #0000ff;\">boolean<\/span> isSelected,<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">                                                 <span style=\"color: #0000ff;\">boolean<\/span> cellHasFocus )<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  {<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">    panel.removeAll();<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">    panel.add( <span style=\"color: #0000ff;\">delegate<\/span>.getListCellRendererComponent( list, value, index,<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">                                                      isSelected, cellHasFocus ) );<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">    <span style=\"color: #0000ff;\">if<\/span> ( Arrays.binarySearch( indexes, index ) &gt;= 0 )<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">      panel.add( <span style=\"color: #0000ff;\">new<\/span> JSeparator(), BorderLayout.PAGE_END );<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">    <span style=\"color: #0000ff;\">return<\/span> panel;<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  }<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">}<\/pre>\n<p>Die Implementierung basiert auf der Idee, jede Komponente in einen Container (JPanel) zu setzen und in diesem Container dann je nach Bedarf ein JSeparatorunten an diesem Container anzuf\u00fcgen. Statt JPanel mit einem JSeparator auszustatten, kann ebenfalls auch ein Border unten gezeichnet werden. Die AnweisungArrays.binarySearch(indexes, index) &gt;= 0 ist als \u00bbcontains\u00ab zu verstehen, also als ein Test, ob der Index im Feld ist \u2013 leider gibt es so eine Methode nicht in der Java API. Wenn der Index im Feld ist, soll der Separator unter der Komponente erscheinen. Dass sich eine Trennlinie auch am Anfang befinden kann, ber\u00fccksichtigt die L\u00f6sung nicht; diese Variante bleibt als \u00dcbungsaufgabe f\u00fcr die Leser.<\/p>\n<p>Diese L\u00f6sung ist einfach und funktioniert gut, denn vorhandene Renderer werden weiterverwendet, was sehr wichtig ist, denn gr\u00f6\u00dfere Swing-Anwendungen nutzen viele eigene Renderer, etwa um Icons und Text zusammenzufassen. Ein Nachteil ist, dass der Separator zu einen Element geh\u00f6rt, und wenn das Element etwa in der Liste ausgew\u00e4hlt wird, steht der Separator mit in der Selektion und ist nicht abgetrennt (das ist aber bei Word genauso).<\/p>\n<p>W\u00e4hrend die vorgestellte Variante in der Praxis gut funktioniert, wollen wir uns noch mit einer alternativen Umsetzung besch\u00e4ftigen. Sie ist deutlich komplexer und auch nicht so flexibel. Die L\u00f6sung basiert auf der Idee, dass die Modelldaten eine Markierung f\u00fcr den Separator enthalten \u2013 die folgende L\u00f6sung nutzt null daf\u00fcr. DaJList oder JComboBox eine null problemlos vertr\u00e4gt, ist die Basis schnell umgesetzt:<\/p>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">JFrame frame = <span style=\"color: #0000ff;\">new<\/span> JFrame();<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">String[] items = { \"<span style=\"color: #8b0000;\">Cambria<\/span>\", <span style=\"color: #0000ff;\"><strong>null<\/strong><\/span>, \"<span style=\"color: #8b0000;\">Arial<\/span>\", \"<span style=\"color: #8b0000;\">Cambria<\/span>\", \"<span style=\"color: #8b0000;\">Verdana<\/span>\", \"<span style=\"color: #8b0000;\">Times<\/span>\" };<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">JComboBox&lt;String&gt; comboBox = <span style=\"color: #0000ff;\">new<\/span> JComboBox&lt;String&gt;( items );<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">frame.add( comboBox );<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">frame.pack();<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">frame.setVisible( <span style=\"color: #0000ff;\">true<\/span> );<\/pre>\n<p>Wenn wir das Programm starten, zeigt es dort, wo das Model eine null liefert, einfach nichts an. Die Selektion dieses null-Elements ist auch m\u00f6glich und f\u00fchrt zu keiner Ausnahme.<\/p>\n<p>Damit Swing das null-Element nicht als Leereintrag anzeigt, verpassen wir unserer JComboBox einen Zellen-Renderer. Der soll immer dann, wenn das Element nullist, ein Exemplar von JSeparator zeichnen. Vom Design ist es das beste, wenn der Zell-Renderer selbst die null-Elemente darstellt, aber das Zeichnen der Nicht-null-Elemente an einen anderen Zell-Renderer abgibt, anstatt diese etwa durch einen BasicComboBoxRenderer (ein JLabel, das ListCellRendererimplementiert) selbst zu renderen \u2013 das w\u00fcrde die Flexibilit\u00e4t der L\u00f6sung massiv einschr\u00e4nken.<\/p>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><span style=\"color: #0000ff;\">package<\/span> com.tutego.insel.ui.list;<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><span style=\"color: #0000ff;\">import<\/span> java.awt.Component;<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><span style=\"color: #0000ff;\">import<\/span> javax.swing.*;<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><span style=\"color: #0000ff;\">public<\/span> <span style=\"color: #0000ff;\">class<\/span> SeparatorAwareListCellRenderer2&lt;E&gt; <span style=\"color: #0000ff;\">implements<\/span> ListCellRenderer&lt;E&gt;<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">{<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  <span style=\"color: #0000ff;\">private<\/span> <span style=\"color: #0000ff;\">final<\/span> ListCellRenderer&lt;? <span style=\"color: #0000ff;\">super<\/span> E&gt; <span style=\"color: #0000ff;\">delegate<\/span>;<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  <span style=\"color: #0000ff;\">public<\/span> SeparatorAwareListCellRenderer2( ListCellRenderer&lt;? <span style=\"color: #0000ff;\">super<\/span> E&gt; <span style=\"color: #0000ff;\">delegate<\/span> )<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  {<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">    <span style=\"color: #0000ff;\">this<\/span>.<span style=\"color: #0000ff;\">delegate<\/span> = <span style=\"color: #0000ff;\">delegate<\/span>;<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  }<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  @Override<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  <span style=\"color: #0000ff;\">public<\/span> Component getListCellRendererComponent( JList&lt;? extends E&gt; list, E value,<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">                                                 <span style=\"color: #0000ff;\">int<\/span> index, <span style=\"color: #0000ff;\">boolean<\/span> isSelected,<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">                                                 <span style=\"color: #0000ff;\">boolean<\/span> cellHasFocus )<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  {<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">    <span style=\"color: #0000ff;\">if<\/span> ( value == <span style=\"color: #0000ff;\">null<\/span> )<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">      <span style=\"color: #0000ff;\">return<\/span> <span style=\"color: #0000ff;\">new<\/span> JSeparator();<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">    <span style=\"color: #0000ff;\">return<\/span> <span style=\"color: #0000ff;\">delegate<\/span>.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus );<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  }<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">}<\/pre>\n<p>Die eigene Klasse SeparatorAwareListCellRenderer2 bekommt einen anderen ListCellRenderer \u00fcbergeben und liefert die Komponenten dieses Delegate-Renderers immer dann, wenn das Element ungleich null ist. Ist es dagegen gleich null, liefert getListCellRendererComponent() ein Exemplar des JSeparators.<\/p>\n<p>Im Beispielprogramm muss der Renderer nun angemeldet werden, und dazu ist Folgendes zu erg\u00e4nzen:<\/p>\n<pre>comboBox.setRenderer(\r\n  new SeparatorAwareListCellRenderer2&lt;String&gt;(comboBox.getRenderer()) );<\/pre>\n<p>Nach dem Start des Programms ist das Ergebnis schon viel besser: Dort, wo vorher die JComboBox eine leere Zeile darstellte, ist nun ein Strich.<\/p>\n<p>Die L\u00f6sung ist jedoch nur ein Etappensieg, denn die Navigation mit der Tastatur durch die Liste zeigt eine Schwachstelle: Das null-Element l\u00e4sst sich ausw\u00e4hlen und erscheint auch als Linie im Editor\/Textfeld. Beheben l\u00e4sst sich das Problem nicht mit dem Renderer, denn der ist nur mit der Darstellung in der Liste beauftragt. Hier muss in die Interna der Swing-Komponente eingegriffen werden. Jede Swing-Komponente hat ein korrespondierendes UI-Delegate, das f\u00fcr das Verhalten und die Darstellung der Komponente verantwortlich ist. F\u00fcr die JComboBox sind das Unterklassen von ComboBoxUI, und zwei Methoden sind besonders interessant:selectNextPossibleValue() und selectPreviousPossibleValue().<\/p>\n<p>Da jede UI-Implementierung ihr eigenes Look and Feel (LAF) mitbringt, m\u00fcssen wir hier eigentlich einen Dekorator bauen und jede Methode bis auf die beiden genannten an das Original weiterleiten, doch das ist jetzt zu viel Arbeit, und so nehmen wir die Basisklasse WindowsComboBoxUI als Basisklasse, denn unser Beispiel nutzt das Windows-LAF. In der Unterklasse implementieren wir eigene Versionen der Methoden selectNextPossibleValue() undselectPreviousPossibleValue(), die so lange die Liste nach oben\/unten laufen m\u00fcssen, bis sie ein Element ungleich null finden.<\/p>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><span style=\"color: #0000ff;\">package<\/span> com.tutego.insel.ui.list;<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><span style=\"color: #0000ff;\">import<\/span> com.sun.java.swing.plaf.windows.WindowsComboBoxUI;<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><span style=\"color: #0000ff;\">public<\/span> <span style=\"color: #0000ff;\">class<\/span> SeparatorAwareComboBoxUI <span style=\"color: #0000ff;\">extends<\/span> WindowsComboBoxUI<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">{<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  @Override<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  <span style=\"color: #0000ff;\">protected<\/span> <span style=\"color: #0000ff;\">void<\/span> selectNextPossibleValue()<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  {<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">    <span style=\"color: #0000ff;\">for<\/span> ( <span style=\"color: #0000ff;\">int<\/span> index = comboBox.getSelectedIndex() + 1;<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">          index &lt; comboBox.getItemCount();<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">          index++ )<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">      <span style=\"color: #0000ff;\">if<\/span> ( comboBox.getItemAt( index ) != <span style=\"color: #0000ff;\">null<\/span> )<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">      {<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">        comboBox.setSelectedIndex( index );<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">        <span style=\"color: #0000ff;\">break<\/span>;<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">      }<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  }<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  @Override<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  <span style=\"color: #0000ff;\">protected<\/span> <span style=\"color: #0000ff;\">void<\/span> selectPreviousPossibleValue()<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  {<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">    <span style=\"color: #0000ff;\">for<\/span> ( <span style=\"color: #0000ff;\">int<\/span> index = comboBox.getSelectedIndex() - 1;<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">          index &gt;= 0;<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">          index-- )<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">      <span style=\"color: #0000ff;\">if<\/span> ( comboBox.getItemAt( index ) != <span style=\"color: #0000ff;\">null<\/span> )<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">      {<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">        comboBox.setSelectedIndex( index );<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">        <span style=\"color: #0000ff;\">break<\/span>;<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">      }<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  }<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">}<\/pre>\n<p>Das UI-Objekt muss ebenfalls im main()-Programm angemeldet werden:<\/p>\n<pre>comboBox.setUI( new SeparatorAwareComboBoxUI() );<\/pre>\n<p>Enth\u00e4lt die Liste null-Elemente, \u00fcberspringt die Tastennavigation \u00fcber die Cursor-Taste diese. Doch auch mit diesem Teilst\u00fcck fehlt ein weiteres Detail: Mit einem Klick l\u00e4sst sich die Linie doch noch ausw\u00e4hlen. Das ist keine Frage des Renderers und auch keine Frage der Tastaturnavigation \u2013 es muss untersagt werden, dass bei der Aktivierung ein null-Element zum Editor kommen kann. Hier ist die Methode setSelectedItem() von JComboBox entscheidend. Denn jedes Element, das selektiert wird \u2013 und dadurch auch in das Textfeld kommt \u2013, geht durch die Methode hindurch. Wenn wir die Methode \u00fcberschreiben und bei null-Elementen einfach nichts tun, wird auch das null-Element nicht selektiert, und im Textfeld bleibt das letzte Element stehen.<\/p>\n<p>Damit auch spezielle Implementierungen von JComboBox von diesem Verhalten profitieren k\u00f6nnen, m\u00fcssen wir wieder einen Dekorator schreiben, doch das kostet zu viel M\u00fche, und so \u00fcberschreibt eine einfache Unterklasse die setSelectedItem()-Methode. (Im Prinzip w\u00e4re auch eine \u00fcberschriebene Methode vonsetSelectedIndex() sinnvoll, denn das k\u00f6nnte eine programmierte Aktivierung von null vermeiden.)<\/p>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><span style=\"color: #0000ff;\">package<\/span> com.tutego.insel.ui.list;<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><span style=\"color: #0000ff;\">import<\/span> javax.swing.*;<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><span style=\"color: #0000ff;\">public<\/span> <span style=\"color: #0000ff;\">class<\/span> SeparatorAwareJComboBox&lt;E&gt; <span style=\"color: #0000ff;\">extends<\/span> JComboBox&lt;E&gt;<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">{<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  @SafeVarargs<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  <span style=\"color: #0000ff;\">public<\/span> SeparatorAwareJComboBox( E... items )<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  {<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">    <span style=\"color: #0000ff;\">super<\/span>( items );<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  }<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  @Override<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  <span style=\"color: #0000ff;\">public<\/span> <span style=\"color: #0000ff;\">void<\/span> setSelectedItem( Object anObject )<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  {<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">    <span style=\"color: #0000ff;\">if<\/span> ( anObject != <span style=\"color: #0000ff;\">null<\/span> )<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">      <span style=\"color: #0000ff;\">super<\/span>.setSelectedItem( anObject );<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  }<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">}<\/pre>\n<p>Im Hauptprogramm muss nur diese spezielle Klasse zum Einsatz kommen und so folgt:<\/p>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">package com.tutego.insel.ui.list;<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">import javax.swing.*;<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><span style=\"color: #0000ff;\">public<\/span> <span style=\"color: #0000ff;\">class<\/span> JComboBoxWithSeparator2<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">{<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  <span style=\"color: #0000ff;\">public<\/span> <span style=\"color: #0000ff;\">static<\/span> void main( <span style=\"color: #0000ff;\">String<\/span>[] args ) throws Exception<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  {<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">    UIManager.setLookAndFeel( UIManager.getSystemLookAndFeelClassName() );<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">\/\/    UIManager.setLookAndFeel( <span style=\"color: #0000ff;\">new<\/span> NimbusLookAndFeel() );<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\"><\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">    JFrame frame = <span style=\"color: #0000ff;\">new<\/span> JFrame();<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">    frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">    <span style=\"color: #0000ff;\">String<\/span>[] items = { \"<span style=\"color: #8b0000;\">Cambria<\/span>\", null, \"<span style=\"color: #8b0000;\">Arial<\/span>\", \"<span style=\"color: #8b0000;\">Verdana<\/span>\", \"<span style=\"color: #8b0000;\">Times<\/span>\" };<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">    JComboBox&lt;<span style=\"color: #0000ff;\">String<\/span>&gt; comboBox = <span style=\"color: #0000ff;\">new<\/span> SeparatorAwareJComboBox&lt;&gt;( items );<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">    comboBox.setRenderer( <span style=\"color: #0000ff;\">new<\/span> SeparatorAwareListCellRenderer2&lt;&gt;(comboBox.getRenderer()) );<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">    comboBox.setUI( <span style=\"color: #0000ff;\">new<\/span> SeparatorAwareComboBoxUI() );<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">    comboBox.setSelectedIndex( 1 );<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">    frame.add( comboBox );<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">    frame.pack();<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">    frame.setVisible( <span style=\"color: #0000ff;\">true<\/span> );<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">  }<\/pre>\n<pre style=\"background-color: #ffffff; margin: 0em; width: 100%; font-family: consolas,'Courier New',courier,monospace; font-size: 13px;\">}<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Standardm\u00e4\u00dfig unterst\u00fctzt die JList und auch JComboBox keine Separatoren, doch die Unterteilung in Segmente ist in der Praxis sehr n\u00fctzlich. Microsoft Word und PowerPoint benutzen sie zum Beispiel, um die zuletzt vom Benutzer ausgew\u00e4hlten Zeichens\u00e4tze prominent oben in der Liste zu haben (Excel dagegen tut dies nicht). Abbildung 9.42: Separator in Words Zeichensatzauswahlliste Wir wollen [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":"","_links_to":"","_links_to_target":""},"categories":[11,10],"tags":[],"class_list":["post-1335","post","type-post","status-publish","format-standard","hentry","category-insel","category-swing"],"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/1335","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/comments?post=1335"}],"version-history":[{"count":4,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/1335\/revisions"}],"predecessor-version":[{"id":1346,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/posts\/1335\/revisions\/1346"}],"wp:attachment":[{"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/media?parent=1335"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/categories?post=1335"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.tutego.de\/blog\/javainsel\/wp-json\/wp\/v2\/tags?post=1335"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}