Tworzenie niestandardowych JButton w Java

głosy
86

Czy istnieje sposób, aby utworzyć JButtonz własnym przycisk graficzny, a nie tylko z obrazem wewnątrz przycisku?

Jeśli nie, to czy istnieje inny sposób tworzyć niestandardowe JButtonw Java?

Utwórz 05/08/2008 o 13:15
źródło użytkownik
W innych językach...                            


5 odpowiedzi

głosy
85

Kiedy po raz pierwszy nauki Java musieliśmy dokonać Yahtzee i pomyślałem, że byłoby fajnie, zamiast tworzyć własne komponenty Swing i pojemniki po prostu wszystko na jednym rysunku JPanel. Korzyść z wystających Swingelementów, oczywiście, jest, aby mieć możliwość dodawania obsługę skrótów klawiaturowych i innych funkcji ułatwień dostępu, że nie można zrobić tylko przez posiadające paint()metoda drukowania ładny obrazek. To nie może być zrobione jednak najlepszy sposób, ale może to być dobry punkt wyjścia dla Ciebie.

Edycja 8/6 - Gdyby nie wynika z obrazów, każdy Die jest przycisk można kliknąć. Pozwoli to przenieść go do DiceContainerdołu. Patrząc na kod źródłowy można zobaczyć, że każdy przycisk Die jest rysowany dynamicznie, w oparciu o jego wartość.

tekst alternatywny
tekst alternatywny
tekst alternatywny

Oto podstawowe kroki:

  1. Utworzyć klasę, która rozciąga JComponent
  2. Wywołanie konstruktora dominująca super()w swoich konstruktorów
  3. Upewnij się, że klasa implementuje MouseListener
  4. Umieścić to w konstruktora:

    enableInputMethods(true);   
    addMouseListener(this);
    
  5. Przestawianie tych metod:

    public Dimension getPreferredSize()  
    public Dimension getMinimumSize()  
    public Dimension getMaximumSize()
    
  6. Przesłonić tę metodę:

    public void paintComponent(Graphics g)
    

Ilość miejsca trzeba pracować podczas rysowania Twój przycisk jest definiowana przez getPreferredSize(), zakładając getMinimumSize()i getMaximumSize()powrót tą samą wartość. Nie za dużo eksperymentował z tym jednak, w zależności od układu użyć dla GUI Twój przycisk mogłaby wyglądać zupełnie inaczej.

I wreszcie, kod źródłowy . W przypadku, gdy brakowało mi niczego.

Odpowiedział 05/08/2008 o 14:03
źródło użytkownik

głosy
32

Tak, jest to możliwe. Jedną z głównych zalet korzystania Swing jest łatwość, z jaką abstrakcyjne kontrole mogą być tworzone i manipuluje.

Oto szybki i brudny sposób przedłużyć istniejącą klasę JButton narysować okrąg po prawej stronie tekstu.

package test;

import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;

import javax.swing.JButton;
import javax.swing.JFrame;

public class MyButton extends JButton {

    private static final long serialVersionUID = 1L;

    private Color circleColor = Color.BLACK;

    public MyButton(String label) {
        super(label);
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);

        Dimension originalSize = super.getPreferredSize();
        int gap = (int) (originalSize.height * 0.2);
        int x = originalSize.width + gap;
        int y = gap;
        int diameter = originalSize.height - (gap * 2);

        g.setColor(circleColor);
        g.fillOval(x, y, diameter, diameter);
    }

    @Override
    public Dimension getPreferredSize() {
        Dimension size = super.getPreferredSize();
        size.width += size.height;
        return size;
    }

    /*Test the button*/
    public static void main(String[] args) {
        MyButton button = new MyButton("Hello, World!");

        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 400);

        Container contentPane = frame.getContentPane();
        contentPane.setLayout(new FlowLayout());
        contentPane.add(button);

        frame.setVisible(true);
    }

}

Zauważ, że nadrzędnymi paintComponent że zawartość przycisku można zmienić, ale że granica jest malowany przez paintBorder metody. GetPreferredSize metoda musi również być zarządzane w celu wspierania dynamicznie zmiany treści. Ostrożność należy zachować podczas pomiaru parametrów czcionki i wymiary obrazu.

Do tworzenia formantu, który można polegać, powyższy kod nie jest właściwe podejście. Wymiary i kolory są dynamiczne w Swing i są zależne od wyglądu i używane. Nawet domyślny Metal wygląd uległ zmianie po drugiej wersji JRE. Byłoby lepiej, aby wdrożyć AbstractButton i zgodne z wytycznymi określonymi przez API Swing. Dobrym punktem wyjścia jest spojrzenie na javax.swing.LookAndFeel i javax.swing.UIManager klas.

http://docs.oracle.com/javase/8/docs/api/javax/swing/LookAndFeel.html

http://docs.oracle.com/javase/8/docs/api/javax/swing/UIManager.html

Zrozumienie anatomii LookAndFeel jest przydatna do pisania kontroli: Tworzenie niestandardowej Look and Feel

Odpowiedział 05/08/2008 o 13:53
źródło użytkownik

głosy
12

zawsze można spróbować Synth wyglądać i czuć. Podać plik xml, który działa jako swego rodzaju stylów, wraz z obrazami, które chcesz użyć. Kod może wyglądać następująco:

try {
    SynthLookAndFeel synth = new SynthLookAndFeel();
    Class aClass = MainFrame.class;
    InputStream stream = aClass.getResourceAsStream("\\default.xml");

    if (stream == null) {
        System.err.println("Missing configuration file");
        System.exit(-1);                
    }

    synth.load(stream, aClass);

    UIManager.setLookAndFeel(synth);
} catch (ParseException pe) {
    System.err.println("Bad configuration file");
    pe.printStackTrace();
    System.exit(-2);
} catch (UnsupportedLookAndFeelException ulfe) {
    System.err.println("Old JRE in use. Get a new one");
    System.exit(-3);
}

Stamtąd dalej i dodać JButton jak zwykle. Jedyną zmianą jest to, że użycie metody ustawNazwe (string), aby określić, jakie przycisk powinien map w pliku xml.

Plik XML może wyglądać następująco:

<synth>
    <style id="button">
        <font name="DIALOG" size="12" style="BOLD"/>
        <state value="MOUSE_OVER">
            <imagePainter method="buttonBackground" path="dirt.png" sourceInsets="2 2 2 2"/>
            <insets top="2" botton="2" right="2" left="2"/>
        </state>
        <state value="ENABLED">
            <imagePainter method="buttonBackground" path="dirt.png" sourceInsets="2 2 2 2"/>
            <insets top="2" botton="2" right="2" left="2"/>
        </state>
    </style>
    <bind style="button" type="name" key="dirt"/>
</synth>

Element wiążą nie określa co do mapowania (w tym przykładzie będzie stosować tę stylizację do jakichkolwiek przycisków, których właściwość nazwa została ustawiona na „brud”).

I kilka przydatnych linków:

http://javadesktop.org/articles/synth/

http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/synth.html

Odpowiedział 05/08/2008 o 13:47
źródło użytkownik

głosy
8

Ja prawdopodobnie będzie milion mil w złym bezpośredni (ale jestem tylko młody: P). ale nie mógł dodać grafikę do panelu, a następnie MouseListener do obiektu graficznego tak, że kiedy użytkownik na swojej graficznej działania jest wstępnie.

Odpowiedział 20/08/2008 o 16:48
źródło użytkownik

głosy
6

Nie zrobiłem rozwój SWING od moich pierwszych klas CS ale jeśli nie został zbudowany w was może po prostu odziedziczyć javax.swing.AbstractButton i tworzyć własne. Powinien być dość prosty drut coś razem z ich istniejących ram.

Odpowiedział 05/08/2008 o 13:30
źródło użytkownik

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more