2008-08-05 12 views
85

Sadece düğme içindeki bir görüntüyle değil, kendi düğme grafiğinizle JButton oluşturmak için bir yol var mı?Java'da özel bir JButton oluşturma

Değilse, özel bir JButton java oluşturmanın başka bir yolu var mı?

cevap

85

biz Yahtzee yapmak zorunda ve bunu çok güzel olacağını düşündüm: LookAndFeel anatomisini anlamak

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

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

yazma denetimler için yararlıdır Yalnızca bir JPanel numaralı telefondan her şeyi çizmek yerine özel Swing bileşenleri ve kapsayıcılar oluşturun. Tabii ki, Swing bileşenlerinin genişletilmesinin yararı, sadece bir paint() yönteminin güzel bir resim basmasıyla yapamayacağınız klavye kısayolları ve diğer erişilebilirlik özellikleri için destek ekleme yeteneğine sahip olmaktır. Ancak en iyi şekilde yapılmayabilir, ancak sizin için iyi bir başlangıç ​​noktası olabilir.

Düzenleme 8/6 - Resimlerden belirgin olmasaydı, her Die, tıklayabileceğiniz bir düğmedir. Bu, aşağıdaki DiceContainer numarasına hareket edecektir. Kaynak koduna bakarak her bir Die düğmesinin, değerine göre dinamik olarak çizildiğini görebilirsiniz.

  1. , sınıfından emin olun kurucularınızdaki JComponent
  2. Çağrı ebeveyn yapıcısı super() genişleten bir sınıf oluşturun: Burada alt text
    alt text

    alt text
    temel adımlardır'yi uygular

  3. yapıcı koy:

    enableInputMethods(true); 
    addMouseListener(this); 
    
  4. ile tahrik, bu yöntem:

    public Dimension getPreferredSize() 
    public Dimension getMinimumSize() 
    public Dimension getMaximumSize() 
    
  5. geçersiz kılma bu yöntem: s

    public void paintComponent(Graphics g) 
    

miktarı Düğmeyi çizerken,tarafından tanımlanan hız, getMinimumSize() ve getMaximumSize() aynı değeri döndürür. Bununla fazla deneme yapmadım, ancak GUI'niz için kullandığınız yerleşime bağlı olarak, düğmeniz tamamen farklı görünebilir.

Son olarak, source code. Bir şey özledim diye.

+1

Merhaba, ilk kod için teşekkürler! Kodunuza 'setActionComme (String Command)' eklemenizi öneririm. Swing’deki olayları filtrelemenin yollarından biridir. (ama sonra bazı şeyleri daha iyi yapmak için eklenebilecek 1001 şey olduğunu iddia edebilirsiniz: P) –

+1

Bütün kodu buraya koyabilir misin? –

+0

Basabileceğiniz bir kalıp oluşturmak için, JButton – ControlAltDel

6

Erken CS sınıflarımdan beri SWING geliştirme işlemini gerçekleştirmedim, ancak eğer oluşturulmamışsa, javax.swing.AbstractButton'u devralabilir ve kendinizinkini yaratabilirsiniz. Varolan çerçeve ile bir şeyler tel bağlamak için oldukça basit olmalı.

12

Her zaman Synth bak & hissini deneyebilirsiniz. Kullanmak istediğiniz resimlerle birlikte bir tür stil sayfası işlevi gören bir xml dosyası sağlarsınız. Kod aşağıdaki gibi görünebilir:

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

Oradan gidip her zamanki gibi JButton ekleyin. Tek değişiklik, düğmenin xml dosyasında eşlemesi gereken şeyi tanımlamak için setName (dize) yöntemini kullanmanızdır.

xml dosyası aşağıdaki gibi görünebilir:

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

eşleme ne var belirten bağlama elemanı (bu örnekte, bu ismi özelliği olarak ayarlanmış herhangi düğmelere o stil uygulanır "kir ").

Ve kullanışlı bağlantıların bir çift:

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

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

32

Evet, bu mümkün. Swing'i kullanmanın başlıca avantajlarından biri, soyut kontrollerin oluşturulup manipüle edilebilmesindeki kolaylıktır.

Mevcut JButton sınıfını metnin sağında bir daire çizmek için genişletmenin hızlı ve kirli bir yolu. paintComponent düğmenin içeriği değiştirilebilmesi, geçersiz kılarak ancak sınır paintBorder yöntemle boyanmış olduğunu

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

} 

Not. İçeriğindeki değişiklikleri dinamik olarak desteklemek için getPreferredSize yönteminin de yönetilmesi gerekir. Yazı tipi ölçümlerini ve görüntü boyutlarını ölçerken dikkatli olunması gerekir.

Güvenebileceğiniz bir denetim oluşturmak için, yukarıdaki kod doğru yaklaşım değildir. Boyutlar ve renkler Swing'de dinamiktir ve kullanılan görünüm ve his bağlıdır. Varsayılan Metal görünümü bile JRE sürümlerinde değişti. AbstractButton'u uygulamak ve Swing API'sı tarafından belirlenen kurallara uymak daha iyi olacaktır. İyi bir başlangıç ​​noktası, javax.swing.LookAndFeel ve javax.swing.UIManager sınıflarına bakmaktır. İlk Java öğreniyordu Creating a Custom Look and Feel

8

Muhtemelen yanlış doğrudan bir milyon mil gidiyor (ama ben sadece genç: P). ancak grafiği bir panele ve daha sonra grafik nesnesine bir mouselistener ekleyemediniz, böylece kullanıcı grafik üzerinde harekete geçtiğinizde.

+1

'daki diğer Simge işlevlerinin yanı sıra setIcon/setPressedIcon öğesinin avantajlarından yararlanarak düz bir eski JButton (alt sınıflama veya özel bir JComponent oluşturma yerine) kullanabilirsiniz. Standart JButton'u mümkünse benim bir düğme türümden daha çok kullanmayı tercih ederim. – Anton