Câu trả lời:
Khi tôi lần đầu tiên học Java, chúng tôi phải tạo ra Yahtzee và tôi nghĩ sẽ rất tuyệt khi tạo các thành phần và vùng chứa Swing tùy chỉnh thay vì chỉ vẽ mọi thứ trên một JPanel
. Tất nhiên, lợi ích của việc mở rộng Swing
các thành phần là có khả năng thêm hỗ trợ cho các phím tắt và các tính năng trợ năng khác mà bạn không thể thực hiện chỉ bằng cách paint()
in một bức tranh đẹp. Tuy nhiên, nó có thể không được thực hiện theo cách tốt nhất, nhưng nó có thể là một điểm khởi đầu tốt cho bạn.
Chỉnh sửa 8/6 - Nếu nó không rõ ràng từ hình ảnh, mỗi Die là một nút bạn có thể nhấp vào. Thao tác này sẽ chuyển nó xuống DiceContainer
bên dưới. Nhìn vào mã nguồn, bạn có thể thấy rằng mỗi nút Die được vẽ động, dựa trên giá trị của nó.
Dưới đây là các bước cơ bản:
JComponent
super()
trong các hàm tạo của bạnMouseListener
Đặt cái này trong hàm tạo:
enableInputMethods(true);
addMouseListener(this);
Ghi đè các phương thức này:
public Dimension getPreferredSize()
public Dimension getMinimumSize()
public Dimension getMaximumSize()
Ghi đè phương thức này:
public void paintComponent(Graphics g)
Khoảng không gian bạn phải làm việc khi vẽ nút của bạn được xác định bởi getPreferredSize()
, giả sử getMinimumSize()
và getMaximumSize()
trả về cùng một giá trị. Tôi chưa thử nghiệm quá nhiều với điều này nhưng, tùy thuộc vào bố cục bạn sử dụng cho GUI của mình mà nút của bạn có thể trông hoàn toàn khác.
Và cuối cùng là mã nguồn . Trong trường hợp tôi bỏ lỡ bất cứ điều gì.
Có, điều này là có thể. Một trong những ưu điểm chính của việc sử dụng Swing là dễ dàng tạo và thao tác các điều khiển trừu tượng.
Đây là một cách nhanh chóng và tiện lợi để mở rộng lớp JButton hiện có để vẽ một vòng tròn ở bên phải văn bản.
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);
}
}
Lưu ý rằng bằng cách ghi đè paintComponent rằng nội dung của nút có thể được thay đổi, nhưng đường viền được vẽ bằng phương thức paintBorder . Các getPreferredSize phương pháp cũng cần phải được quản lý để thay đổi sự ủng hộ động đến nội dung. Cần phải cẩn thận khi đo số liệu phông chữ và kích thước hình ảnh.
Để tạo điều khiển mà bạn có thể dựa vào, đoạn mã trên không phải là cách tiếp cận chính xác. Kích thước và màu sắc linh hoạt trong Swing và phụ thuộc vào giao diện được sử dụng. Ngay cả giao diện Kim loại mặc định cũng đã thay đổi trên các phiên bản JRE. Sẽ tốt hơn nếu triển khai AbstractButton và tuân thủ các nguyên tắc do API Swing đưa ra. Một điểm khởi đầu tốt là xem xét các lớp javax.swing.LookAndFeel và 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
Hiểu cấu trúc của LookAndFeel rất hữu ích cho việc viết các điều khiển: Tạo Giao diện và Cảm nhận Tùy chỉnh
Bạn luôn có thể thử giao diện Synth. Bạn cung cấp tệp xml hoạt động như một loại biểu định kiểu, cùng với bất kỳ hình ảnh nào bạn muốn sử dụng. Mã có thể trông như thế này:
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);
}
Từ đó, hãy tiếp tục và thêm JButton của bạn như bạn thường làm. Thay đổi duy nhất là bạn sử dụng phương thức setName (string) để xác định những gì nút sẽ ánh xạ đến trong tệp xml.
Tệp xml có thể trông giống như sau:
<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>
Phần tử liên kết ở đó chỉ định những gì sẽ ánh xạ tới (trong ví dụ này, nó sẽ áp dụng kiểu đó cho bất kỳ nút nào có thuộc tính tên đã được đặt thành "dơ").
Và một số liên kết hữu ích:
http://javadesktop.org/articles/synth/
http://docs.oracle.com/javase/tutorial/uiswing/lookandfeel/synth.html
Tôi có lẽ sẽ là một triệu dặm trong sai trực tiếp (nhưng tôi chỉ trẻ: P). nhưng bạn không thể thêm đồ họa vào bảng điều khiển và sau đó là một mouselistener vào đối tượng đồ họa để khi người dùng trên đồ họa hành động của bạn được định dạng trước.
Tôi đã không thực hiện phát triển SWING kể từ các lớp CS đầu tiên của mình nhưng nếu nó không được tích hợp sẵn, bạn có thể kế thừa javax.swing.AbstractButton
và tạo của riêng mình. Sẽ khá đơn giản để kết nối một cái gì đó với nhau với khuôn khổ hiện có của chúng.