# Eigene Border für Buttons



## Andreas1989 (26. Mrz 2009)

Hallo ich bins mal wieder...
Ich möchte für meine jButtons eigene standard Borders und eigene RolloverBorders zeichnen. Die Methode, welche du standard Border zeichnet heit paintBorder und ist eine statische Methode von jComponent. Wenn ich nun andere standard Border und andere RolloverBorder haben möchte, muss ich dann die Klasse jComponent vererben und die benötigten Methoden überschreiben, oder bin ich da an der falschen stelle?

Gruß 
 Andreas


----------



## Schandro (26. Mrz 2009)

suchst du vllt. eher das hier?
JButton#setBorder(Border newBorder);


----------



## Andreas1989 (26. Mrz 2009)

Hallo Schandro,
nee die Methode kenn ich.
Standardmässig soll mein Button keine Border haben, sobald ich über den Border drüber fahre soll die rechte und die untere Border Schwarz werden, die linke und die obere weis. Wenn ich draufklicke genau anderst rum. Dadruch soll der Button blasitscher werden. Von Haus aus gibt es leider keine Methode mit der ich das machen kann - soweit mir bekannt. Deswegen sollte ich wissen, welche Methoden dafür verantwortlich sind - wenns jemand weis.

Danke.


----------



## Schandro (26. Mrz 2009)

naja, entweder du realisierst es einfach in paintComponent
oder du machst ein Implementierung vom Interface Border wo du dynamisch entscheidest wie genau der Border sich malen soll. (Border müssen ja nicht unbedingt "statisch" aussehen)


----------



## Verjigorm (26. Mrz 2009)

Ein Rahmen ist eine Klasse, die die Schnittstelle Border implementiert. Swing stellt einige Standardrahmen zur Verfügung.

Du schreibst dir eine Klasse, die Border implementiert.

Du musst u.a. die Funktion paintBorder vom Interface implementieren, in der du dann deinen Rahmen zeichnen kannst.
Dein Button weiss ja auch, wann die Maus drüber ist etc. kannste alles abfragen.


```
@Override
    public void paintBorder(Component c, Graphics g, int x, int y, int width,
            int height) {
        // TODO Auto-generated method stub

    }
```


----------



## Andreas1989 (26. Mrz 2009)

Hallo,
soweit hab ich das jetzt gemacht. Hab aber noch mit einem Schwirgkeiten.

```
public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
//....
}
```
Wenn ich nun diese Methode in meinem Hauptprogramm aufrufe um die Ränder zu Zeichnen weis ich erlich gesagt nicht was für eine Graphics ich übergeben muss. Wenn ich im Programm selbst eine tempGraphics anlege
	
	
	
	





```
Graphics tempGraphics = null)
```
und die dann übergebe bekomme ich eine NullPointerException.
Was mach ich falsch...


----------



## Verjigorm (26. Mrz 2009)

Die Funktion musst du NICHT aufrufen, sondern nur mit Leben füllen


----------



## Schandro (26. Mrz 2009)

du musst sie nur INDIREKT mit repaint aufrufen, wenn etwas anders gemalt werden soll


----------



## Andreas1989 (26. Mrz 2009)

Aso.. jo, jetzt tut es. Wie kann ich ermitteln auf welchem Button ich gerade bin? bzw. welchen ich gerade drücke. Ich will ja standardmässig kein Border nur wenn ich drüber fahre und ihn anklicke..
Danke!


----------



## Ebenius (26. Mrz 2009)

Hier ein einfaches Beispiel: [Highlight=Java]final Border simpleRolloverButtonBorder = new Border() {

  public void paintBorder(
        Component c,
        Graphics g,
        int x,
        int y,
        int width,
        int height) {
    final AbstractButton button = (JButton) c;
    final ButtonModel model = button.getModel();
    if (model.isRollover()) {
      g.setColor(model.isArmed() ? Color.BLACK : Color.WHITE);
      g.drawLine(x, y, x + width - 1, y);
      g.drawLine(x, y, x, y + height - 1);
      g.setColor(model.isArmed() ? Color.WHITE : Color.BLACK);
      g.drawLine(x, y + height - 1, x + width - 1, y + height - 1);
      g.drawLine(x + width - 1, y, x + width - 1, y + height - 1);
    }
  }

  public boolean isBorderOpaque() {
    return false;
  }

  public Insets getBorderInsets(Component c) {
    return new Insets(1, 1, 1, 1);
  }
};[/Highlight]
Ebenius


----------



## Andreas1989 (26. Mrz 2009)

hallo,
wo ist der Fehler?


> Exception in thread "main" java.lang.InstantiationError: test.JMyButton
> at layout.<init>(layout.java:33)
> at layout.main(layout.java:216)


Haupt Programm

```
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;
import test.*;
public class layout extends JFrame {
//..
private JMyButton jBRefresh = new JMyButton();
//..
jBRefresh.setBounds(x, y, w, h);
jBRefresh.setText(tempString);
jBRefresh.setFocusPainted(false);
jBRefresh.setBackground(cDefault);
jBRefresh.setBorderPainted(true);
jBRefresh.setIcon(iArtikel);
//..
```
klasse JMyButton

```
public abstract class JMyButton extends JButton implements Border
{  
  final Border simpleRolloverButtonBorder = new Border() 
  {
    @Override
    public void paintBorder(
        Component c,
        Graphics g,
        int x,
        int y,
        int width,
        int height) 
    {
      final AbstractButton button = (JButton) c;
      final ButtonModel model = button.getModel();
      if (model.isRollover()) 
      {
        g.setColor(model.isArmed() ? Color.BLACK : Color.WHITE);
        g.drawLine(x, y, x + width - 1, y);
        g.drawLine(x, y, x, y + height - 1);
        g.setColor(model.isArmed() ? Color.WHITE : Color.BLACK);
        g.drawLine(x, y + height - 1, x + width - 1, y + height - 1);
        g.drawLine(x + width - 1, y, x + width - 1, y + height - 1);
      }
    }
    public boolean isBorderOpaque() 
    {
      return false;
    }

    public Insets getBorderInsets(Component c) 
    {
      return new Insets(1, 1, 1, 1);
    }
  };
}
```

Gruß Andreas


----------



## Ebenius (26. Mrz 2009)

Welche Zeile ist denn zeile 33 in layout.java?


----------



## Andreas1989 (26. Mrz 2009)

Hallo, 
Zeile 33 ist:   private JMyButton jBRefresh = new JMyButton();
da wird auch zum ersten mal ein JMyButton angelegt.
Es muss also was mit der Klasse JMyButton net stimmen


----------



## Ebenius (27. Mrz 2009)

Wieso ist die Klasse JMyButton abstrakt und warum sagt Dir das der Compiler nicht?

Ebenius


----------



## hoveman (7. Apr 2009)

ich habe das gleiche problem.
@Ebenius: dein quellcode funktioniert wunderbar. nur wenn ich das look and feel änder, dann geht es leider nicht mehr. 


```
public class Main {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        try {
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        } catch (ClassNotFoundException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        } catch (UnsupportedLookAndFeelException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new GUI().setVisible(true);
            }
        });
    }

}
```


```
public class GUI extends javax.swing.JFrame {

    /** Creates new form GUI */
    public GUI() {
        initComponents();
        initButton();
    }

    private void initButton() {
        final Border simpleRolloverButtonBorder = new Border() {

            public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {
                final AbstractButton button = (JButton) c;
                final ButtonModel model = button.getModel();
                System.out.println("paintBorder: ("+x+","+y+","+width+","+height+")"+" isRollover: "+model.isRollover());
                if (model.isRollover()) {
                  g.setColor(model.isArmed() ? Color.BLACK : Color.WHITE);
                  g.drawLine(x, y, x + width - 1, y);
                  g.drawLine(x, y, x, y + height - 1);
                  g.setColor(model.isArmed() ? Color.WHITE : Color.BLACK);
                  g.drawLine(x, y + height - 1, x + width - 1, y + height - 1);
                  g.drawLine(x + width - 1, y, x + width - 1, y + height - 1);
                }
            }

            public boolean isBorderOpaque() {
                return false;
            }

            public Insets getBorderInsets(Component c) {
                return new Insets(1, 1, 1, 1);
            }
        };
        jButton1.setBorder(simpleRolloverButtonBorder);
    }

    .......
}
```

mein os: win xp


----------



## Ebenius (7. Apr 2009)

hoveman hat gesagt.:


> dein quellcode funktioniert wunderbar. nur wenn ich das look and feel änder, dann geht es leider nicht mehr.


Hab kein XP zum testen. Funktioniert's, wenn Du dem Button setRolloverEnabled(true) sagst?

Ebenius


----------



## hoveman (7. Apr 2009)

Ebenius hat gesagt.:


> Hab kein XP zum testen. Funktioniert's, wenn Du dem Button setRolloverEnabled(true) sagst?
> 
> Ebenius


 
heissen dank... jetzt funktionierts. komisch nur, dass ich es bei dem windows look and feel auf true setzten muss, bei dem standart look and feel aber nicht???:L

edit: jetzt hätte ich nur noch eine frage: wie kann ich links und rechts, sowie oben und unten mehr abstand zum text machen? x sowie y sind ja schon 0 ???:L sonst hätte ich zu width und height was dazu addiert und bei x und y was abgezogen


----------



## Ebenius (7. Apr 2009)

hoveman hat gesagt.:


> heissen dank... jetzt funktionierts. komisch nur, dass ich es bei dem windows look and feel auf true setzten muss, bei dem standart look and feel aber nicht???:L


Dazu sagt die API-Doc: 





> The default value for the rolloverEnabled property is false. Some look and feels might not implement rollover effects; they will ignore this property.





hoveman hat gesagt.:


> jetzt hätte ich nur noch eine frage: wie kann ich links und rechts, sowie oben und unten mehr abstand zum text machen? x sowie y sind ja schon 0 ???:L sonst hätte ich zu width und height was dazu addiert und bei x und y was abgezogen


Du willst den Innenabstand vom Text zum Rahmen erhöhen? Das geht mit button.setMargin(new Insets(10, 10, 10, 10).

Ebenius


----------



## hoveman (7. Apr 2009)

cool danke... nächste mal werd ich ein bischen mehr doku lesen. war aber gerade etwas in zeitdruck


----------



## Ebenius (7. Apr 2009)

hoveman hat gesagt.:


> cool danke... nächste mal werd ich ein bischen mehr doku lesen. war aber gerade etwas in zeitdruck


Kein Problem. 

Happy Hacking!
Ebenius


----------

