سؤال

هذا السؤال مرتبط بسؤالي السابق كيفية توليد الإحداثيات الديكارتية (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.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top