जावा में एक कस्टम JButton बनाना


97

क्या JButtonअपने खुद के बटन ग्राफिक के साथ बनाने का एक तरीका है और न केवल बटन के अंदर की छवि के साथ?

यदि नहीं, तो क्या JButtonजावा में रिवाज बनाने का एक और तरीका है ?

जवाबों:


91

जब मैं पहली बार जावा सीख रहा था तो हमें याहत्ज़ी बनाना पड़ा और मैंने सोचा कि यह सब एक पर सब कुछ खींचने के बजाय कस्टम स्विंग घटकों और कंटेनरों को बनाने के लिए अच्छा होगा JPanelSwingनिस्संदेह, फैले हुए घटकों का लाभ , कीबोर्ड शॉर्टकट और अन्य एक्सेसिबिलिटी सुविधाओं के लिए समर्थन जोड़ने की क्षमता है, जो कि आप paint()एक सुंदर चित्र प्रिंट विधि द्वारा नहीं कर सकते । यह सबसे अच्छा तरीका नहीं हो सकता है, लेकिन यह आपके लिए एक अच्छा शुरुआती बिंदु हो सकता है।

संपादित करें 8/6 - यदि यह छवियों से स्पष्ट नहीं था, प्रत्येक डाई एक बटन है जिसे आप क्लिक कर सकते हैं। यह इसे नीचे तक ले जाएगा DiceContainer। स्रोत कोड को देखकर आप देख सकते हैं कि प्रत्येक डाई बटन गतिशील रूप से खींचा गया है, इसके मूल्य के आधार पर।

वैकल्पिक शब्द
वैकल्पिक शब्द
वैकल्पिक शब्द

यहाँ बुनियादी कदम हैं:

  1. एक क्लास बनाएं जो फैली हुई हो JComponent
  2. super()अपने कंस्ट्रक्टरों में पैरेंट कंस्ट्रक्टर को बुलाओ
  3. सुनिश्चित करें कि आप कक्षा को लागू करते हैं MouseListener
  4. इसे कंस्ट्रक्टर में डालें:

    enableInputMethods(true);   
    addMouseListener(this);
  5. इन विधियों को ओवरराइड करें:

    public Dimension getPreferredSize()  
    public Dimension getMinimumSize()  
    public Dimension getMaximumSize()
  6. इस विधि को ओवरराइड करें:

    public void paintComponent(Graphics g)

आप काम करने के लिए है स्थान की मात्रा है जब आपके बटन ड्राइंग के साथ द्वारा परिभाषित किया गया है getPreferredSize(), यह मानते हुए getMinimumSize()और getMaximumSize()समान मान। मैंने इसके साथ बहुत अधिक प्रयोग नहीं किया है, लेकिन आपके GUI के लिए आपके द्वारा उपयोग किए गए लेआउट के आधार पर आपका बटन पूरी तरह से अलग दिख सकता है।

और अंत में, स्रोत कोड । मामले में मैं कुछ भी याद किया।


1
नमस्ते, पहले कोड के लिए धन्यवाद! मैं आपके कोड में एक 'setActionComme (स्ट्रिंग कमांड)' जोड़ने का सुझाव दूंगा। यह स्विंग में घटनाओं को फ़िल्टर करने के तरीकों में से एक है। (लेकिन तब आप तर्क दे सकते हैं कि 1001 चीजें हैं जो चीजों को थोड़ा बेहतर बनाने के लिए जोड़ा जा सकता है: P)
जेसन रोजर्स

1
एक डाई बनाने के लिए जिसे आप दबा सकते हैं, आप वास्तव में setIcon / setPressedIcon के साथ-साथ JButton में अन्य आइकॉन कार्यक्षमता का लाभ उठाकर एक सादे पुराने JButton (उपवर्ग या एक कस्टम JComponent बनाने के बजाय) का उपयोग कर सकते हैं
ControlAltDel

34

हां, यह संभव है। स्विंग का उपयोग करने के लिए मुख्य पेशेवरों में से एक आसानी है जिसके साथ अमूर्त नियंत्रण बनाया जा सकता है और हेरफेर कर सकता है।

पाठ के दाईं ओर एक वृत्त खींचने के लिए मौजूदा JButton वर्ग का विस्तार करने का एक त्वरित और गंदा तरीका यहां दिया गया है।

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

}

ध्यान दें कि PaintComponent को ओवरराइड करके बटन के कंटेंट को बदला जा सकता है, लेकिन बॉर्डर को पेंटबॉर्डर विधि द्वारा चित्रित किया गया है । GetPreferredSize विधि भी सामग्री के लिए गतिशील रूप से समर्थन परिवर्तन करने के लिए प्रबंधित किया जाना चाहिए। फ़ॉन्ट मेट्रिक्स और छवि आयामों को मापते समय देखभाल की आवश्यकता होती है।

एक नियंत्रण बनाने के लिए जिस पर आप भरोसा कर सकते हैं, उपरोक्त कोड सही दृष्टिकोण नहीं है। आयाम और रंग स्विंग में गतिशील हैं और उपयोग किए जा रहे लुक और फील पर निर्भर हैं। यहां तक ​​कि डिफ़ॉल्ट धातु रूप JRE संस्करणों में बदल गया है। बेहतर होगा कि AbstractButton को लागू किया जाए और स्विंग एपीआई द्वारा निर्धारित दिशा-निर्देशों के अनुरूप हो। एक अच्छा प्रारंभिक बिंदु javax.swingलुका.फंड और javax.swing.UIManager वर्गों को देखना है ।

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

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

नियंत्रण लिखने के लिए LookAndFeel की शारीरिक रचना को समझना उपयोगी है: कस्टम लुक और फील बनाना


13

आप हमेशा सिंथ लुक और फील कर सकते हैं। आप एक एक्सएमएल फ़ाइल प्रदान करते हैं जो एक प्रकार की स्टाइलशीट के रूप में कार्य करती है, साथ ही आप जो भी चित्र उपयोग करना चाहते हैं। कोड इस तरह दिख सकता है:

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

वहाँ से, जाओ और अपने जेबटन को जोड़ो जैसे कि आप सामान्य रूप से करेंगे। एकमात्र परिवर्तन यह है कि आप सेटनाम (स्ट्रिंग) विधि का उपयोग यह पहचानने के लिए करते हैं कि बटन को xml फ़ाइल में क्या मैप करना चाहिए।

Xml फ़ाइल इस तरह दिख सकती है:

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

बाइंड एलिमेंट निर्दिष्ट करता है कि मैप में क्या करना है (इस उदाहरण में, यह उस स्टाइल को किसी भी बटन पर लागू करेगा, जिसके नाम संपत्ति "गंदगी" पर सेट की गई है)।

और उपयोगी लिंक की एक जोड़ी:

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

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


8

मैं शायद एक मिलियन मील की दूरी पर गलत प्रत्यक्ष (लेकिन मैं केवल युवा हूं: पी) में जा रहा हूं। लेकिन क्या आप ग्राफिक को किसी पैनल में नहीं जोड़ सकते हैं और फिर ग्राफिक ऑब्जेक्ट के लिए एक मूसलिस्टेनर बना सकते हैं ताकि जब ग्राफिक पर उपयोगकर्ता आपकी कार्रवाई पूर्वनिर्मित हो।


1
यह काम करेगा, लेकिन यदि संभव हो तो मैं अपने प्रकार के बटन बनाने की तुलना में मानक जेबटन का उपयोग करना पसंद करूंगा।
एंटोन

7

मैंने अपनी प्रारंभिक सीएस कक्षाओं के बाद से विकास नहीं किया है, लेकिन अगर यह आप में नहीं बनाया गया है तो आप विरासत में javax.swing.AbstractButtonही अपना निर्माण कर सकते हैं। उनके मौजूदा ढांचे के साथ कुछ तार करने के लिए बहुत सरल होना चाहिए।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.