Opprette en egendefinert JButton i Java

stemmer
88

Er det en måte å skape et JButtonmed egen knapp grafikk og ikke bare med et bilde inne på knappen?

Hvis ikke, er det en annen måte å lage en egendefinert JButtoni java?

Publisert på 05/08/2008 klokken 12:15
kilden bruker
På andre språk...                            


5 svar

stemmer
85

Da jeg først lærte Java måtte vi gjøre Yahtzee, og jeg trodde det ville være kult å opprette egendefinerte Swing komponenter og beholdere i stedet for bare å tegne alt på ett JPanel. Fordelen med strekker Swingkomponenter, selvfølgelig, er å ha muligheten til å legge til støtte for hurtigtaster og andre tilgjengelighetsfunksjoner som du ikke kan gjøre bare ved å ha en paint()metode skrive ut et pent bilde. Det kan ikke gjøres den beste måten men, men det kan være et godt utgangspunkt for deg.

Rediger 8/6 - Hvis det ikke var tydelig fra bildene, er hvert Die en knapp du kan klikke. Dette vil flytte den til DiceContainernedenfor. Ser på kildekoden kan du se at hver Die knappen er trukket dynamisk, basert på sin verdi.

alt tekst
alt tekst
alt tekst

Her er de grunnleggende trinnene:

  1. Lag en klasse som strekker JComponent
  2. Call foreldre konstruktør super()i dine konstruktører
  3. Sørg for at du klassen implementerer MouseListener
  4. Sett denne i konstruktøren:

    enableInputMethods(true);   
    addMouseListener(this);
    
  5. Styre disse metodene:

    public Dimension getPreferredSize()  
    public Dimension getMinimumSize()  
    public Dimension getMaximumSize()
    
  6. Styre denne metoden:

    public void paintComponent(Graphics g)
    

Hvor mye plass du har å jobbe med når du tegner knappen er definert av getPreferredSize(), forutsatt getMinimumSize()og getMaximumSize()returnere samme verdi. Jeg har ikke eksperimentert for mye med dette, men, avhengig av oppsettet du bruker for GUI knappen kan se helt annerledes ut.

Og til slutt, kildekoden . I tilfelle jeg savnet noe.

Svarte 05/08/2008 kl. 13:03
kilden bruker

stemmer
32

Ja, dette er mulig. En av de viktigste fordeler for bruk Swing er den letthet med hvilken de abstrakte kontrollene kan opprettes og manipulerer.

Her er en rask og skitne måte å forlenge eksisterende JButton klassen til å tegne en sirkel til høyre for teksten.

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);
    }

}

Vær oppmerksom på at ved å overstyre paintComponent at innholdet knappen kan endres, men at grensen er malt av den paintBorder metoden. Den getPreferredSize Metoden trenger også å bli administrert for å støtte endringer i innholdet dynamisk. Hensyn må bli tatt når man måler font beregninger og bildedimensjoner.

For å skape en kontroll som du kan stole på, er koden ovenfor ikke riktig tilnærming. Dimensjoner og farger er dynamiske i Swing og er avhengig av utseendet som brukes. Selv standard Metal utseende har endret seg over JRE-versjoner. Det ville være bedre å gjennomføre AbstractButton og i samsvar med de retningslinjer som er fastsatt av Swing API. Et godt utgangspunkt er å se på de javax.swing.LookAndFeel og javax.swing.UIManager klasser.

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

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

Forstå anatomi LookAndFeel er nyttig for å skrive kontroller: Opprette en egendefinert utseende og funksjonalitet

Svarte 05/08/2008 kl. 12:53
kilden bruker

stemmer
12

Du kan alltid prøve Synth ser og føler. Du gir en xml fil som fungerer som en slags stil, sammen med alle bildene du vil bruke. Koden kan se slik ut:

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);
}

Derfra går på og legge til JButton som du normalt ville. Den eneste endringen er at du bruker setName (streng) metode for å identifisere hva knappen skal kartlegge til i xml filen.

Xml fil kan se slik ut:

<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>

Bindings element det spesifiserer hva som skal tilordnes til (i dette eksempelet, vil det gjelde at styling til noen knapper navn som eiendommen har blitt satt til "skitt").

Og et par nyttige linker:

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

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

Svarte 05/08/2008 kl. 12:47
kilden bruker

stemmer
8

Jeg sannsynligvis kommer en million miles i feil direkte (men jeg er bare ung: P). men kan ikke du legge til grafikk i et panel og deretter en mouselistener til den grafiske objektet slik at når brukeren på den grafiske handlingen er preformed.

Svarte 20/08/2008 kl. 15:48
kilden bruker

stemmer
6

Jeg har ikke gjort SWING utvikling siden min tidlige serie klasser, men hvis det ikke ble bygget i du kan bare arve javax.swing.AbstractButtonog lage dine egne. Bør være ganske enkelt å koble noe sammen med sine eksisterende rammer.

Svarte 05/08/2008 kl. 12:30
kilden bruker

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