كيفية الحصول على تنسيق Image على JPanel
-
25-09-2019 - |
سؤال
هذا السؤال مرتبط بسؤالي السابق كيفية توليد الإحداثيات الديكارتية (x ، y) من Gridbaglayout؟
لقد نجحت في الحصول على إحداثيات كل صور ، ولكن عندما قمت بفحص الإحداثي من خلال (system.out.println) ووضع الصور على الشاشة ، يبدو أنه خطأ. على سبيل المثال ، إذا كان من الواضح على الشاشة أن النقطة X للصورة الأولى موجودة على الخلية 2 وهي تنسيق 20 ، لكن البرنامج يعرض x = 1.
هنا جزء من الكود:
public Grid (){
setPreferredSize(new Dimension(600,600));
....
setLayout(new GridBagLayout());
GridBagConstraints gc = new GridBagConstraints();
gc.weightx = 1d;
gc.weighty = 1d;
gc.insets = new Insets(0, 0, 0, 0);//top, left, bottom, and right
gc.fill = GridBagConstraints.BOTH;
JLabel[][] label = new JLabel[ROWS][COLS];
Random rand = new Random();
// fill the panel with labels
for (int i=0;i<IMAGES;i++){
ImageIcon icon = createImageIcon("myPics.jpg");
int r, c;
do{
//pick random cell which is empty
r = (int)Math.floor(Math.random() * ROWS);
c = (int)Math.floor(Math.random() * COLS);
} while (label[r][c]!=null);
//randomly scale the images
int x = rand.nextInt(50)+30;
int y = rand.nextInt(50)+30;
Image image = icon.getImage().getScaledInstance(x,y, Image.SCALE_SMOOTH);
icon.setImage(image);
JLabel lbl = new JLabel(icon); // Instantiate GUI components
gc.gridx = r;
gc.gridy = c;
add(lbl, gc); //add(component, constraintObj);
label[r][c] = lbl;
}
راجعت الإحداثي من خلال هذا الرمز:
Component[] components = getComponents();
for (Component component : components) {
System.out.println(component.getBounds());
}
المحلول
يمكنك استخدام SwingUtilities
convertPointToScreen()
و convertPointFromScreen()
للتحويل بين الإحداثيات الشاشة والمكونات.
إضافة: إليك مثال بسيط استخدمته عند محاولة فهم كيفية تحرك المكونات وتغيير حجمها تحت تأثير مدير التخطيط.
public class MyPanel extends JPanel {
public MyPanel() {
super(new GridLayout(4, 4));
for (int i = 0; i < 16; i++) {
JPanel panel = new JPanel(new GridLayout());
panel.add(new CenterLabel());
this.add(panel);
}
}
private static void create() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new MyPanel());
f.pack();
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
create();
}
});
}
private static class CenterLabel extends JLabel {
public CenterLabel() {
this.setHorizontalAlignment(JLabel.CENTER);
this.setVerticalAlignment(JLabel.CENTER);
this.setOpaque(true);
this.setBackground(Color.lightGray);
this.setBorder(BorderFactory.createLineBorder(Color.blue));
this.setPreferredSize(new Dimension(160, 100));
this.addComponentListener(new ComponentAdapter() {
@Override
public void componentResized(ComponentEvent e) {
int w = e.getComponent().getWidth();
int h = e.getComponent().getHeight();
CenterLabel.this.setText("[" + w/2 + "\u253C" + h/2 + "]");
}
});
}
}
}
نصائح أخرى
إذا كان من الواضح على الشاشة أن النقطة X للصورة الأولى موجودة على الخلية 2 وهي تنسيق 20 ، لكن البرنامج يظهر x = 1.
ستحتوي الصورة الأولى على إحداثيات X/Y من 0/0. سيكون للصور الثانية إحداثيات 1/0. قيم X/Y من الإزاحة من 0. هل هذا ما تتحدث عنه؟
أم أن المستمع الخاص بك قد تمت إضافته إلى الصورة وليس اللوحة في هذه الحالة تحتاج إلى تحويل إحداثيات الصورة إلى إحداثيات اللوحة. تحقق من فئة Swingutability لأساليب للقيام بذلك.
إذا كنت بحاجة إلى مزيد من المساعدة نشر SSCCE.