Een aangepaste JButton in Java

stemmen
86

Is er een manier om een te maken JButtonmet uw eigen grafische knoop en niet alleen met een afbeelding in de knop?

Zo niet, dan is er een andere manier om een aangepaste maken JButtonin java?

De vraag is gesteld op 05/08/2008 om 13:15
bron van user
In andere talen...                            


5 antwoorden

stemmen
85

Toen ik voor het eerst Java leerde moesten we Yahtzee te maken en ik dacht dat het zou cool zijn om aangepaste Swing componenten en containers te creëren in plaats van alleen het tekenen alles op één JPanel. Het voordeel van de uitbreiding van Swingcomponenten, is natuurlijk de mogelijkheid om ondersteuning toe te voegen voor sneltoetsen en andere voorzieningen voor dat je niet zomaar kunt doen door het hebben van een hebben paint()methode drukt u een mooi plaatje. Het is misschien niet de beste manier worden gedaan echter, maar het kan een goed uitgangspunt voor je.

Bewerken 8/6 - Als het niet blijkt uit de foto's, die elk Die is een knop kunt u klikken. Dit maakt het verplaatsen naar de DiceContainervolgende. Kijkend naar de source code kunt u zien dat elk Die knop dynamisch wordt opgesteld op basis van de waarde ervan.

Alt-tekst
Alt-tekst
Alt-tekst

Hier zijn de basisstappen:

  1. Maak een klasse die zich uitstrekt JComponent
  2. Call ouder constructeur super()in uw constructeurs
  3. Zorg ervoor dat je klasse implementeert MouseListener
  4. Zet dit in de constructor:

    enableInputMethods(true);   
    addMouseListener(this);
    
  5. Override deze methoden:

    public Dimension getPreferredSize()  
    public Dimension getMinimumSize()  
    public Dimension getMaximumSize()
    
  6. Overschrijven van deze methode:

    public void paintComponent(Graphics g)
    

De hoeveelheid ruimte die je hebt om mee te werken bij het opstellen van uw knop wordt gedefinieerd door getPreferredSize(), in de veronderstelling getMinimumSize()en getMaximumSize()terug te keren op dezelfde waarde. Ik heb niet te veel geëxperimenteerd met deze, maar, afhankelijk van de lay-out die u gebruikt voor uw GUI uw knoop zou helemaal anders uitzien.

En tot slot, de broncode . In het geval dat miste ik iets.

antwoordde op 05/08/2008 om 14:03
bron van user

stemmen
32

Ja, dit is mogelijk. Een van de belangrijkste pro's voor het gebruik van Swing is het gemak waarmee de abstracte controles kunnen worden gemaakt en manipuleert.

Hier is een snelle en vuile manier om de bestaande JButton klasse uit te breiden tot een cirkel te tekenen aan de rechterkant van de tekst.

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

}

Merk op dat door dwingende paintComponent dat de inhoud van de toets kan worden gewijzigd, maar dat de grens is geschilderd door de paintBorder methode. De getPreferredSize methode moet ook om dynamisch te ondersteunen wijzigingen van de inhoud worden beheerd. Zorg moet worden genomen bij het meten lettertype metrics en afmetingen van het beeld.

Voor het maken van een controle die u kunt vertrouwen op, de bovenstaande code is niet de juiste aanpak. Afmetingen en kleuren zijn dynamisch in Swing en zijn afhankelijk van de look en feel worden gebruikt. Zelfs de standaard Metal uiterlijk is veranderd over JRE-versies. Het zou beter zijn om te implementeren AbstractButton en voldoen aan de door de Swing API te stellen richtlijnen. Een goed startpunt is om te kijken naar de javax.swing.LookAndFeel en javax.swing.UIManager klassen.

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

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

Inzicht in de anatomie van LookAndFeel is nuttig voor het schrijven van de controles: Een aangepaste look en feel

antwoordde op 05/08/2008 om 13:53
bron van user

stemmen
12

Je kan altijd proberen de Synth look & feel. U levert een XML-bestand dat fungeert als een soort stylesheet, samen met eventuele foto's die u wilt gebruiken. De code kan er zo uitzien:

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

Van daar, ga op en voeg uw JButton zoals je normaal zou doen. De enige verandering is dat u de methode setName (string) gebruiken om te bepalen wat de knop moet toewijzen aan in het XML-bestand.

Het XML-bestand kan er zo uitzien:

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

De bind element er aangegeven welke toewijzen aan (in dit voorbeeld, het zal die styling van toepassing op alle knoppen waarvan de naam eigenschap is ingesteld op "vuil").

En een paar handige links:

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

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

antwoordde op 05/08/2008 om 13:47
bron van user

stemmen
8

Ik ga waarschijnlijk een miljoen mijl in de verkeerde directe (maar ik ben alleen jonge: P). maar kon niet u de afbeelding een MouseListener toe te voegen aan een panel en vervolgens naar het grafische object zodat wanneer de gebruiker op de grafische uw actie is voorgevormd.

antwoordde op 20/08/2008 om 16:48
bron van user

stemmen
6

Ik heb niet gedaan SWING ontwikkeling sinds mijn vroege CS klassen, maar als het niet werd gebouwd in je kon gewoon erven javax.swing.AbstractButton en maak je eigen. Moet vrij eenvoudig om iets samen met hun bestaande kader draad.

antwoordde op 05/08/2008 om 13:30
bron van user

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