# Eigene Buttons



## Andreas1989 (23. Mrz 2009)

Hallo zusammen,
ich habe mir bereits eine Art eigene Buttons geschrieben - eben ein jPanel erstellt und diesem ein paar Listener zugeteilt.
Ich glaube aber nicht dass das der richtige Weg ist.
Kann mir jemand erklären, wie richtig eigene Knöpfe erstellt werden? Gibt es dazu ein Java Doc oder ein gutes Buch? 
Die Buttons sollen schon Grafisch anderst aussehen und in einer eigenen Klasse stehen.
Kann mir da jemand weiterhelfen wie ich an das Problem ran gehe? 

Vielen Dank

Gruß


----------



## Ebenius (23. Mrz 2009)

Andreas1989 hat gesagt.:


> Hallo zusammen,
> ich habe mir bereits eine Art eigene Buttons geschrieben - eben ein jPanel erstellt und diesem ein paar Listener zugeteilt.
> Ich glaube aber nicht dass das der richtige Weg ist.


Ich auch nicht. 



Andreas1989 hat gesagt.:


> Kann mir jemand erklären, wie richtig eigene Knöpfe erstellt werden? Gibt es dazu ein Java Doc oder ein gutes Buch?
> Die Buttons sollen schon Grafisch anderst aussehen und in einer eigenen Klasse stehen.
> Kann mir da jemand weiterhelfen wie ich an das Problem ran gehe?


Von JButton ableiten, eigenes ButtonUI implementieren.

Ebenius


----------



## 0x7F800000 (23. Mrz 2009)

Andreas1989 hat gesagt.:


> Hallo zusammen,
> ich habe mir bereits eine Art eigene Buttons geschrieben - eben ein jPanel erstellt und diesem ein paar Listener zugeteilt.
> Ich glaube aber nicht dass das der richtige Weg ist.


:autsch: ne, nicht wirklich. 


> Kann mir jemand erklären, wie richtig eigene Knöpfe erstellt werden? Gibt es dazu ein Java Doc oder ein gutes Buch?


Galileo Computing :: Java ist auch eine Insel (8. Auflage) – 16 Grafische Oberflächen mit Swing
Das Ding nennt sich JButton. Wird auch einfach nur erstellt, und da wird ein ActionListener drangehängt.



> Die Buttons sollen schon Grafisch anderst aussehen und in einer eigenen Klasse stehen.
> Kann mir da jemand weiterhelfen wie ich an das Problem ran gehe?


mit den normalen buttons kann man doch schon so viele sachen anstellen: Icons setzen, farben ändern, Rahmen entfernen, oder einfach ein anderes LAF setzen und schauen wie's dann aussieht... Wenn einem ganz langeweilig ist, dann kann man ja vielleicht auch die paintComponent() irgendwie komplett überschreiben...


[Edit: Verschwörungstheorie: Java-Forum ist von einer dunklen Macht besessen und beantwortet daher alle Fragen nach exakt 13 Minuten, weil 13 eine soo böse zahl ist^^ ]


----------



## max40 (23. Mrz 2009)

Wenn du generell die normalen JButton nicht brauchst, könntest du am Look&Fell was machen,
ansonsten würde ich mir eine Klasse von javax.swing.AbstractButton ableiten! Ich denke damit hast du den Grundaufbau!


----------



## Gast2 (23. Mrz 2009)

Ja ich denke am besten ist du machst/erstellst dir schicke eigene Bilder und setzt die oder überschreibst die paintComponent und malst je nach Status des Buttons dein Icon...
z.B. 
[HIGHLIGHT="Java"]

    class CButton extends JButton {

        @Override
        public void paintComponents(Graphics g) {
            // TODO Auto-generated method stub
            super.paintComponents(g);

            if (getModel().isRollover()) {
                // zeichne bild
            }

            // usw.
        }
    }
[/HIGHLIGHT]


----------



## max40 (23. Mrz 2009)

Muss man wirklich paintComponents überschreiben?
Am Button kann mal RolloverIcon etc setzen, diese müssten doch verwendet werden oder ?



SirWayne hat gesagt.:


> Ja ich denke am besten ist du machst/erstellst dir schicke eigene Bilder und setzt die oder überschreibst die paintComponent und malst je nach Status des Buttons dein Icon...
> z.B.
> [HIGHLIGHT="Java"]
> 
> ...


----------



## Gast2 (23. Mrz 2009)

ja aber ich weiß nicht wie es dann mit dem Rand usw. ist und wenn das Bild zu klein ist...
keine ahnung müsste man ausprobieren...
ich weiß ja nicht was er alles selbst machen will ...


----------



## Andreas1989 (23. Mrz 2009)

Hallo zusammen,
erst mal Danke für die Antworten. Man kann mit jButton doch ein paar nette sachen machen.
Ich habe mich aber vorhin zu pauschal ausgedrückt. Was ich vorhab ist eine kleine Navigationsleiste zu erstellen. Bild der Planung im Anhang(Über Farben und Icons müssen wir nicht reden . Das ist nur ein Konzept).
Hatte bis jetzt vor mir die Navigationsleiste aus JPanels zusammen zubauen und mit MouseListener zu belegen. Das Aktive Feld sollte einen Helleren Hintergrund haben wie die anderen. Wenn ich über ein Feld trüber fahre sollte es einen Rahmen oder so was in der Art bekommen.

Und dafür wollte ich mir dann eine eigene Klasse schreibe(z.B. ANavBar). Zusätzlich wollte ich Methoden wie setBounds etc. verwenden oder Methoden um anzugeben wie viele Navigations Punkte ich brauche.

Wie würdet Ihr mir nun so ein Vorhaben empfehlen?


----------



## Ebenius (23. Mrz 2009)

Zwei Möglichkeiten es besser zu machen:

*JList mit eigenem Renderer*
Das Panel links ist eigentlich eine Liste. Sie hat mehrere Einträge untereinander, kann eine Auswahl gesondert handhaben. Also JList nehmen und eigenen Renderer drauf, der JToggleButtons darstellt.

*JTabbedPane*
Wenn die Buttons links gleich ein Panel umschalten sollen und Du das ganze mehrfach wiederverwenden willst, dann bildet das mittlere Panel mit der Navigationsleiste zusammen eigentlich ein JTabbedPane das nur anders aussehen soll. In diesem Fall würde ich ein eigenes TabbedPaneUI schreiben und die JTabbedPane-Komponente benutzen.

Die eigentliche Darstellung wie in Deinem Beispiel geht vollständig ohne selbst Zeichenroutinen zu schreiben. All das kann JButton von Haus aus. BTW: JToggleButton ist hierfür ohnehin besser geeignet als JButton.

Ebenius


----------



## Andreas1989 (23. Mrz 2009)

Hallo,
ich glaube, dass das JTabbedPane das richtige für mich ist. Von der Funktion hab ich mir das auch so vorgestellt, dass beim Klick auf ein Tab ein anderes JPanel dargestellt wird.

Also vielen Dank euch allen - mal kucken wie weit ich komme 

Gruß


----------



## Gast2 (23. Mrz 2009)

Eventuell kannst du dir auch noch das CardLayout anschauen wäre für sowas auch eine Variante...


----------



## Ebenius (23. Mrz 2009)

Jupp. CardLayout brauchst Du bei der UI-Implementierung des JTabbedPane.


----------



## Andreas1989 (23. Mrz 2009)

Hallo Ebenius,
bis jetzt habe ich noch keine Erfahrungen mit dem Überschreiben/Neuschreiben von einer TabbedPaneUI. Gibt es dafür irgendein FAQ, oder hast du mir ein anderen Tipp wie ich an das Thema herran gehen kann?

Gruß
 Andreas


----------



## Ebenius (23. Mrz 2009)

FAQ zum selbst schreiben von UIs kenne ich nicht, gibt's aber vielleicht trotzdem. Schau Dir den Quelltext der Basic-XYZ-UIs an (also BasicTabbedPaneUI, wenn Du ein solches implementieren willst). Es schadet auch nicht, sich das ein oder andere UI anzuschauen, das man gar nicht bearbeiten will, nur um ein Gefühl dafür zu bekommen, wie man heran geht. Nimm einfache UIs zum lernen, also ganz sicher kein BasicTreeUI.

Leite von der Basic-Implementierung (BasicTabbedPaneUI) ab, wenn sich das nicht mit Deinem Vorhaben stört, oder implementiere alles neu (Implementiere TabbedPaneUI). Letzteres ist fast nie nötig.

Der allgemeeine Ablauf ist im ComponentUI-Interface beschrieben, von dem erben alle UIs.

Viel Erfolg!
Ebenius


----------



## Andreas1989 (23. Mrz 2009)

hallo Ebenius,
also auf den ersten Blick wirkt die Datei BasicTabbedPaneUI.java nahezu erschlagent auf mich - fast 4000 Code. Ich denke damit werde ich aber fertig.
Womit ich jetzt aber noch Denk Schwierigkeiten habe, ist beim Ableiten der Klasse. Wie soll der anfangs Code meiner neuen Klasse aussehen, damit ich bestehende Methoden  von  BasicTabbedPaneUI überschreiben kann und dass diese auch bei einem neuen TabbedPane angewendet werden. Wäre super wenn du mir hierzu ein Code Beispiel geben könntest.

Gruß Andi


----------



## 0x7F800000 (23. Mrz 2009)

Andreas1989 hat gesagt.:


> also auf den ersten Blick wirkt die Datei BasicTabbedPaneUI.java nahezu erschlagent auf mich - fast 4000 Code. Ich denke damit werde ich aber fertig.



Öhm, Ebenius, könntest du vielleicht bitte nochmal kurz erläutern, wieso er da unbedingt irgendwas von diesem (?) *javax.swing.plaf.basic.BasicTabbedPaneUI* ableiten soll, die normale* JTabbedPane* macht es ja auch nicht ???:L oder?


----------



## Ebenius (23. Mrz 2009)

Klar.

*BasicMyTabbedPaneUI*
[Highlight=Java]import java.awt.Color;
import java.awt.Insets;

import javax.swing.JComponent;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicTabbedPaneUI;

public class BasicMyTabbedPaneUI extends BasicTabbedPaneUI {

  public static ComponentUI createUI(JComponent c) {
    return new BasicMyTabbedPaneUI();
  }

  @Override
  protected void installDefaults() {
    super.installDefaults();
    highlight = Color.RED.brighter();
    lightHighlight = Color.RED.brighter().brighter();
    shadow = Color.RED.darker();
    darkShadow = Color.RED.darker().darker();
    focus = Color.BLACK;
    tabInsets = new Insets(50, 50, 50, 50);
  }
}[/Highlight]
*JMyTabbedPane*
[Highlight=Java]import javax.swing.*;

public class JMyTabbedPane extends JTabbedPane {

  private static final String uiClassID = "MyTabbedPaneUI";

  static {
    final String pkgName = JMyTabbedPane.class.getPackage().getName();
    if (UIManager.get(uiClassID) == null) {
      UIManager.put(uiClassID, pkgName + ".BasicMyTabbedPaneUI");
    }
  }

  @Override
  public String getUIClassID() {
    return uiClassID;
  }
}[/Highlight]
Ebenius


----------



## 0x7F800000 (23. Mrz 2009)

Alles klar, bin nun überzeugt. Muss mir das bei gelegenheit auch mal anschauen


----------



## Gast2 (23. Mrz 2009)

Ich versteh nicht ganz warum ihr überhaupt eine JTabbedPane nehmen wollt??
Wegen den 5 Button links? Also wenn er noch nicht soviel erfahrung hat würde ich in der mitte ein cardlayout nehmen und links ein panel wo er die buttons platziert...
die kann er ja leicht gestalten da buttons im notfall auch html untersützen was er bei den hier nicht braucht... Also so aufwendig sind die Buttons ja nicht...


----------



## Andreas1989 (23. Mrz 2009)

Hallo SirWayne,
natürlich könnte ich das ganze auch ziemlich einfach machen. Ist eh alles nur Spielerrei. Mir geht aber darum etwas zu lernen. Das denk ich tu ich mit den JTabbedPane´s auf jeden Fall. Ich weis zwar noch nicht ob ich mir da nicht zu viel vornehme - aber hinterher ist man immer Schlauer. Und wenn ichs grad mach - dann kann ich es auch grad "richtig" machen.

Gruß
--- EDIT:
@Ebenius
In deinem Beispiel Code hast du doch die Methode installDefaults() vom BasicTabbedPaneUI überschrieben. Hast du noch zusätzlich was hinzugefügt damit die Methode überschrieben wird?? wenn ich den Klasse: BasicMyTabbedPaneUI folgendes ergenze ergibt sich keine Änderung:
[HIGHLIGHT="Java"]protected void paintTabBorder(Graphics g, int tabPlacement,
                                  int tabIndex,
                                  int x, int y, int w, int h,
                                  boolean isSelected ) {
        g.setColor(lightHighlight);

        switch (tabPlacement) {
          case LEFT:
              g.drawLine(x+1, y+h-2, x+1, y+h-2); // bottom-left highlight
              g.drawLine(x, y+2, x, y+h-3); // left highlight
              g.drawLine(x+1, y+1, x+1, y+1); // top-left highlight
              g.drawLine(x+2, y, x+w-1, y); // top highlight

              g.setColor(Color.BLUE);
              g.drawLine(x+2, y+h-2, x+w-1, y+h-2); // bottom shadow

              g.setColor(Color.BLUE);
              g.drawLine(x+2, y+h-1, x+w-1, y+h-1); // bottom dark shadow
              break;
          case RIGHT:
              g.drawLine(x, y, x+w-3, y); // top highlight

              g.setColor(Color.BLUE);
              g.drawLine(x, y+h-2, x+w-3, y+h-2); // bottom shadow
              g.drawLine(x+w-2, y+2, x+w-2, y+h-3); // right shadow

              g.setColor(Color.BLUE);
              g.drawLine(x+w-2, y+1, x+w-2, y+1); // top-right dark shadow
              g.drawLine(x+w-2, y+h-2, x+w-2, y+h-2); // bottom-right dark shadow
              g.drawLine(x+w-1, y+2, x+w-1, y+h-3); // right dark shadow
              g.drawLine(x, y+h-1, x+w-3, y+h-1); // bottom dark shadow
              break;
          case BOTTOM:
              g.drawLine(x, y, x, y+h-3); // left highlight
              g.drawLine(x+1, y+h-2, x+1, y+h-2); // bottom-left highlight

              g.setColor(Color.BLUE);
              g.drawLine(x+2, y+h-2, x+w-3, y+h-2); // bottom shadow
              g.drawLine(x+w-2, y, x+w-2, y+h-3); // right shadow

              g.setColor(Color.BLUE);
              g.drawLine(x+2, y+h-1, x+w-3, y+h-1); // bottom dark shadow
              g.drawLine(x+w-2, y+h-2, x+w-2, y+h-2); // bottom-right dark shadow
              g.drawLine(x+w-1, y, x+w-1, y+h-3); // right dark shadow
              break;
          case TOP:
          default:
              g.drawLine(x, y+2, x, y+h-1); // left highlight
              g.drawLine(x+1, y+1, x+1, y+1); // top-left highlight
              g.drawLine(x+2, y, x+w-3, y); // top highlight

              g.setColor(Color.BLUE);
              g.drawLine(x+w-2, y+2, x+w-2, y+h-1); // right shadow

              g.setColor(Color.BLUE);
              g.drawLine(x+w-1, y+2, x+w-1, y+h-1); // right dark-shadow
              g.drawLine(x+w-2, y+1, x+w-2, y+1); // top-right shadow
        }
    }[/HIGHLIGHT]
Die Ränder werden immer noch Rot angezeit, so wie in installDefaults() festgelegt. An was liegt das??

Gruß


----------



## Ebenius (24. Mrz 2009)

Andreas1989 hat gesagt.:


> Hast du noch zusätzlich was hinzugefügt damit die Methode überschrieben wird??


Nö. mein gesamter Code steht oben.



Andreas1989 hat gesagt.:


> Die Ränder werden immer noch Rot angezeit, so wie in installDefaults() festgelegt. An was liegt das??


Öhm, an Zeile fünf vielleicht? Tausch sie doch mal testweise aus durch: [HIGHLIGHT="Java"]    g.setColor(Color.YELLOW);[/HIGHLIGHT]
Ebenius


----------

