2011-11-23 23 views
6

Gần đây tôi đã đọc chủ đề này (Creating a custom button in Java) về cách tạo các nút tùy chỉnh trong java bằng cách mở rộng lớp JButton, tuy nhiên tất cả các giải pháp về chủ đề này sử dụng đồ họa được vẽ trong java.Làm thế nào để tạo một JButton tùy chỉnh trong java với một cơ sở hình ảnh?

Tôi muốn có nút của mình dựa trên hình ảnh nút mà tôi đã vẽ trong photoshop. Vì vậy, tôi đã cố gắng áp dụng những gì tôi đọc trong chuỗi đó với kết quả này:

import javax.swing.*; 
import java.awt.*; 

public class nextButton extends JButton { 
    @Override 
     protected void paintComponent(Graphics g) { 
     Image image = new ImageIcon("nextButton.png").getImage(); 
     g.drawImage(image,0,0,this); 
} 

    @Override 
    public Dimension getPreferredSize() { 
     Dimension size = super.getPreferredSize(); 
     size.setSize(75, 150); 
     return size; 
    } 
} 

Khi tôi chạy chương trình chính đã thêm nút này vào JPanel nó không hiển thị. Tôi cho rằng đó có thể là một trong nhiều lý do:

a) Kích thước của JButton không khớp với hình ảnh? b) Tôi chưa tải hình ảnh đúng cách. Trong các ghi chú, giảng viên của tôi đã cho tôi viết mã hình ảnh hiển thị chỉ với "imageName.png" không có đường dẫn tệp nên tôi không biết đây có phải là cách chính xác hay không, hoặc chương trình sẽ biết cách tải hình ảnh như thế nào . c) Cái gì khác ngoài kiến ​​thức của tôi cho đến nay.

Nếu có ai biết cách giải quyết điều này, tôi sẽ rất biết ơn.

Cảm ơn bạn rất nhiều!

+0

một vài ý kiến, ít nhiều liên quan đến vấn đề của bạn: a) ghi đè paintComponent là bất hợp pháp b) không bao giờ _change_ bất cứ điều gì trong getter c) cụ thể, setSize được thực hiện bởi LayoutManager dù sao, sẽ không có hiệu ứng trong một ứng dụng sane d) nó là chính xác để ghi đè getPreferredSize và trả về một gợi ý kích thước hợp lý, dựa trên nội bộ của thành phần, ở đây có thể là kích thước của hình ảnh e) tải hình ảnh trong sơn (không có nâng nặng bao giờ hết trong chu kỳ sơn!), thay vì tải nó một lần tại thời điểm xây dựng – kleopatra

+0

btw, hãy tìm hiểu quy ước đặt tên java và gắn bó với chúng – kleopatra

Trả lời

4

Đối với một, bạn nên sử dụng ImageIO.read(new File("somefile.png")) để tải Image. Lưu ý rằng nếu không có đường dẫn tuyệt đối nào được chỉ định, nó sẽ mặc định tương ứng với thư mục làm việc . Nếu bạn đang chạy ra khỏi nhật thực, đó là thư mục dự án. Trong một cái lọ, đó là thư mục mà bình chứa trong (trừ khi có quy định khác).

Xem http://docs.oracle.com/javase/tutorial/2d/images/loadimage.html để có giải thích về cách tải hình ảnh chính xác (cũng nói cách thực hiện nó từ bên trong một applet).

Ngoài ra, bạn nên tải hình ảnh lần, sau đó tái sử dụng nó cho mỗi lần lặp sơn:

BufferedImage image; 

public nextButton() { 
    try { 
     image = ImageIO.read(new File("nextButton.png")); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

@Override 
protected void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    g.drawImage(image, 0, 0, null); 
} 

@Override 
public Dimension getPreferredSize() { 
    return new Dimension(image.getWidth(), image.getHeight()); 
} 

Hãy cho tôi biết nếu làm việc này cho bạn (hãy chắc chắn để đưa png của bạn trong thư mục làm việc!).

+0

a) không sử dụng setXXSize, thay vì ghi đè getPreferredSize (bạn đang phân lớp rồi, không có lý do gì để cẩu thả ;-) b) paintComponent ghi đè là bất hợp pháp, nó _must_ được thực hiện để tuân thủ hợp đồng opacity của nó – kleopatra

+0

-1 ahhh ... chỉ cần nhìn thấy chỉnh sửa của bạn, đó là chỉ đơn giản là sai: trọng getPref _certainly_ là con đường để đi. – kleopatra

+0

@kleopatra ah xin lỗi về điều đó, tôi đoán tôi đã sai. Sửa lỗi với bản chỉnh sửa. Tôi quá quen với việc làm việc với các công cụ Swing cùng nhau, tôi sẽ lưu ý về điều setSize trong đầu. Việc thiếu 'super.paintComponent' là một sai lầm trong phần của tôi mà tôi biết là không chính xác, vì vậy tôi cũng đã sửa lỗi đó. – jli

5

Tôi cũng đã hỏi câu hỏi này sớm hơn. Giải pháp tôi tìm thấy hiệu quả nhất là thực sự làm điều này, thay vì vẽ.

ImageIcon icon = new ImageIcon("pathOfImageHere.png"); 
JButton button = new JButton(icon); 

Vì vậy, hãy đặt nút đó thành hình ảnh. Bây giờ những gì tôi đã chọn để làm là làm cho nút vô hình và loại bỏ tất cả các biên giới. Vì vậy, tôi đã làm điều này tiếp theo:

button.setOpaque(false); 
button.setContentAreaFilled(false); 
button.setBorderPainted(false); 
button.setFocusPainted(false); 
+0

Morevoer, chúng ta có thể xác định các trạng thái nút khác nhau (xem: [link] (http://www.leepoint.net/notes-java/GUI/components/20buttons/23buttonicons.html)). Giải pháp của bạn với mẹo đó hoạt động hoàn hảo! – Alexxx

Các vấn đề liên quan