2012-12-07 133 views
4

我在另一個具有複雜JPanels結構和代碼的項目中面臨這個問題。SwingUtilities.convertPoint()返回負值

在那裏,我必須在標籤和麪板是動態選擇和JLabel的應該是JPanel的盛大隆重-...-孩子下面的代碼片段

Point point = label.getLocation(); 
Point point2 = SwingUtilities.convertPoint(label.getParent(), point, panel); 

那麼爲什麼問題是在什麼情況下SwingUtilities.convertPoint()可以返回負值,如果源和目的地有父子關係?這可能嗎?

此代碼演示了負座標問題,但是panel22不是標籤的父項。

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Point; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.SwingUtilities; 

public class NegativeLocation { 
    public static void main(String[] args) { 
     new NegativeLocation(); 
    } 

    public NegativeLocation() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       JFrame frame = new JFrame(); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 

       JPanel panel1 = new JPanel() { 
        @Override 
        public Dimension getPreferredSize() { 
         return new Dimension(600, 400); 
        } 
       }; 

       JPanel panel21 = new JPanel() { 
        @Override 
        public Dimension getPreferredSize() { 
         return new Dimension(300, 400); 
        } 
       }; 
       panel1.add(panel21); 

       JPanel panel22 = new JPanel() { 
        @Override 
        public Dimension getPreferredSize() { 
         return new Dimension(300, 400); 
        } 
       }; 
       panel1.add(panel22); 

       JPanel panel3 = new JPanel() { 
        @Override 
        public Dimension getPreferredSize() { 
         return new Dimension(300, 400); 
        } 
       }; 
       panel21.add(panel3); 

       JLabel label = new JLabel("Label"); 
       panel3.add(label); 

       frame.getContentPane().add(panel1); 
       frame.setPreferredSize(new Dimension(600, 400)); 

       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 

       Point point = label.getLocation(); 
       Point point2 = SwingUtilities.convertPoint(label.getParent(), point, panel21); 
       Point point3 = SwingUtilities.convertPoint(label.getParent(), point, panel22); 

       System.out.println(point2); 
       System.out.println(point3); 
      } 
     }); 
    } 
} 

所以輸出

java.awt.Point[x=134,y=10] 
java.awt.Point[x=134,y=-395] 

UPD:基本上,我需要得到label相對的位置panel21。我如何修改這一行來存檔它?

Point point = label.getLocation(); 
Point point2 = SwingUtilities.convertPoint(label.getParent(), point, panel21); 
+0

這是因爲你通過的JLabel的位置,但通過標籤的父權,所以現在所在的位置信息是無效的 – MadProgrammer

+0

@MadProgrammer但'的getLocation()'給出的結果相對給父母。所以我指定父源爲源。我的邏輯有什麼問題? –

+0

但是,convert位置方法需要孩子在座標空間中的位置,而不是父母 – MadProgrammer

回答

4

看看下面的例子...

enter image description here

public class TestLocation01 { 

    public static void main(String[] args) { 
     new TestLocation01(); 
    } 

    public TestLocation01() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JPanel outter = new JPanel(new BorderLayout()); 
       outter.setBorder(new CompoundBorder(new LineBorder(Color.RED), new EmptyBorder(10, 10, 10, 10))); 
       JPanel inner = new JPanel(new GridBagLayout()); 
       inner.setBorder(new CompoundBorder(new LineBorder(Color.BLUE), new EmptyBorder(10, 10, 10, 10))); 
       JLabel label = new JLabel("Testing"); 
       inner.add(label); 
       outter.add(inner); 

       JLabel below = new JLabel("Below"); 

       JFrame frame = new JFrame("Test"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(outter); 
       frame.add(below, BorderLayout.SOUTH); 
       frame.setSize(200, 200); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 

       System.out.println("lable.location: " + label.getLocation()); 
       System.out.println("label to inner: " + SwingUtilities.convertPoint(label, new Point(0, 0), inner)); 
       System.out.println("label to outter: " + SwingUtilities.convertPoint(label, new Point(0, 0), outter)); 
       System.out.println("label.parent to inner: " + SwingUtilities.convertPoint(label.getParent(), new Point(0, 0), inner)); 
       System.out.println("label.parent to outter: " + SwingUtilities.convertPoint(label.getParent(), new Point(0, 0), outter)); 
       System.out.println("label to frame: " + SwingUtilities.convertPoint(label, new Point(0, 0), frame)); 
       System.out.println("label.getParent to frame: " + SwingUtilities.convertPoint(label.getParent(), new Point(0, 0), frame)); 
       System.out.println("outter to label: " + SwingUtilities.convertPoint(outter, new Point(0, 0), label)); 
       System.out.println("label to below: " + SwingUtilities.convertPoint(label, new Point(0, 0), below)); 
       System.out.println("below to label: " + SwingUtilities.convertPoint(below, new Point(0, 0), label)); 
      } 
     }); 
    }   
} 

如果我通過label爲源組件,其產生(在我的系統)以下的輸出

lable.location: java.awt.Point[x=65,y=62] 
label to inner: java.awt.Point[x=65,y=62] 
label to outter: java.awt.Point[x=76,y=73] 
label.parent to inner: java.awt.Point[x=0,y=0] 
label.parent to outter: java.awt.Point[x=11,y=11] 
label to frame: java.awt.Point[x=76,y=95] 
label.getParent to frame: java.awt.Point[x=11,y=33] 
outter to label: java.awt.Point[x=-76,y=-73] 
label to below: java.awt.Point[x=76,y=-89] 
below to label: java.awt.Point[x=-76,y=89] 

,我根據label與我嘗試座標空間的組件之間的關係獲得相對位置轉換爲。如果我通過了label的父母,我使用的父座標空間代替,這勢必會產生不正確的結果

如果你看看labelbelow之間的關係是有意義的,你會得到負結果,如label是上方和的below

+0

+1爲例來說明該方法 – StanislavL

7

對我來說這是正確的行爲。想象一下。主面板包含位置x = 0 y = 100的孩子。如果您將主面板0,0點轉換爲小孩,它會返回0,-100。 事實上,哪個組件是其中的父組件並不重要。邏輯是添加(全部減去)父級呈現子級時應用於圖形的所有translate()調用。

+0

@Nikolay Kuznetsov您是否試圖添加與JPanel不同的顏色?setBackground,然後調整JFrame的大小,現在我明白Stas回答後,座標是否正確,你鏈接指向另一個JPanel(不是父母,然後是負數:-) – mKorbel

+0

@mKorbel和Stas,請看我的更新,我需要以獲得標籤相對於面板21的位置。我的方法是否正確? –

+0

我認爲你上面提到的方法是正確的point point2 = SwingUtilities.convertPoint(label,new Point(0,0),panel21); – StanislavL