2013-04-18 2 views
1

Я использую Java Swing для своего приложения, и я хочу использовать JViewport, чтобы показать фрагмент некоторой панели, подобной холсту, позади порта. Но почему-то видовое окно никогда не позиционирует свое мнение, поэтому должно быть что-то, что я делаю. Что я делаю неправильно, почему этот код не работает?JViewport не позиционирует свое мнение?

Ниже приведен пример того, что я делаю в более крупном и сложном масштабе.

public class MyApp 
{ 
    // THIS IS A TEMPORARY TEST TO GET VIEWPORT WORKING 
    public static void main(String[] args) 
    { 
    JFrame frame = new JFrame(); 
    JViewport viewport = new JViewport(); 
    viewport.setOpaque(true); 
    viewport.setBackground(Color.GRAY); 
    frame.add(viewport, BorderLayout.CENTER); 
    JPanel canvas = new JPanel(null); 
    canvas.setBackground(Color.CYAN); 
    viewport.setView(canvas); 
    viewport.setViewSize(new Dimension(500, 500)); 
    viewport.setExtentSize(new Dimension(300, 300)); 
    viewport.setPreferredSize(new Dimension(300, 300)); 

    // item one 
    JLabel label = new JLabel("This is a 32x32 box"); 
    label.setOpaque(true); 
    label.setBackground(Color.GREEN); 
    label.setIcon(Sprites.BOX2.getSprite()); 
    label.setBounds(0, 0, 200, 32); // position upper left, 200 wide 
    label.setHorizontalAlignment(SwingConstants.LEFT); 
    canvas.add(label); 

    // item two 
    JLabel label2 = new JLabel("This is a 32x32 wall"); 
    label2.setOpaque(true); 
    label2.setBackground(Color.ORANGE); 
    label2.setIcon(Sprites.WALL1.getSprite()); 
    label2.setBounds(300, 468, 200, 32); // position lower right, 200 wide 
    label2.setHorizontalAlignment(SwingConstants.RIGHT); 
    label2.setHorizontalTextPosition(SwingConstants.LEFT); 
    canvas.add(label2); 

    // this should scroll the canvas to the left and up, so the box becomes invisible and the wall visible 
    viewport.setViewPosition(new Point(200, 200)); 

    frame.pack(); 
    frame.setLocationRelativeTo(null); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setVisible(true); 
    } 
} 

Результатом является то, что «холст» просто торчит на 0,0, она никогда не переходит в 200,200, как я с setViewPostition(). Это содержимое отлично позиционируется хорошо, независимо от нулевого менеджера макетов. Я просто написал холст для JPanel для простоты, но это действительно сложный JLayeredPane.

+0

См. Также ['ScrollPanePaint'] (http://stackoverflow.com/a/3518047/230513), [_et al_] (http://stackoverflow.com/a/10097538/230513). – trashgod

ответ

4

Есть несколько проблем, в вашем случае:

  • используется null -layout/абсолютного позиционирование: прекратить делать это ... навсегда. Это плохая практика, очень плохая и неприятная привычка, которая всегда приводит к одной и той же точке: множество проблем.
  • Не называйте setPreferredSize(): либо использовать соответствующий LayoutManager или переопределить getPreferredSize()
  • Рассмотрим реализацию Scrollable для холста и где getPreferredScrollableViewportSize() вернется new Dimension(300, 300) (размер видового экрана целенаправленные степени)
  • Вызов SetSize()/setExtentSize() в значительной степени бесполезно, потому что это будет преодолено LayoutManager.
+0

+1 последняя точка может быть - используйте JLayer (Java7) вместо JViewport – mKorbel

+0

1) Я понимаю, что менеджеры макетов лучше, чем позиционирование, но это не проблема. Содержимое холста идеально, но сам холст неправильно расположен. 2 и 4). Вы имеете в виду, что мне нужно добавить менеджера макета в область просмотра? Я думал, что это не нужно. 3) Я рассмотрю создание холста ** Прокручиваемый **. –

+0

@JackMcKalling В окне просмотра есть свой собственный LayoutManager. Предпочтительный размер окна просмотра основан на 1), если в представлении viewport реализуется Scrollable, значение, возвращаемое getPreferredScrollableViewPortSize 2) else, предпочтительным размером. Вид viewport получает размер, определяемый значением, возвращаемым getPreferredSize() –

Смежные вопросы