2013-01-07 83 views
1

duke.png - >duke.png圖像獲取垂直滾動窗格視口消失

arrowToLeft.gif - >arrowToKeft

arrowToRight.gif - >enter image description here

我需要的,我想一個UI在Swing中描繪網絡設備的圖形表示。爲此,我只是加載多個圖像並逐個重疊顯示設備的當前狀態。我必須支持縮放這個視圖。縮放代碼看起來像這樣。

public class LayeredPaneTest{ 
     private JLayeredPane layeredPane; 
     private JScrollPane scrollPane; 
     private static double MIN_ZOOM_VALUE = 0.60; // 1.0; 
     private static double MAX_ZOOM_VALUE = 2.0; 
     private static final int LAYER1 = 0; 
     private static final int LAYER2 = 1; 
     private static final int LAYER3 = 3; 
     private double scaleFactor = 1.0; 
     private JInternalFrame internalFrame = 
      new JInternalFrame("LayeredPaneTest",false, false, false, false); 

     public LayeredPaneTest(){ 
      loadView(); 
     } 

     public JInternalFrame getView(){ 
      return internalFrame; 
     } 

     private void loadView(){ 
      ((javax.swing.plaf.basic.BasicInternalFrameUI)internalFrame.getUI()) 
       .setNorthPane(null); 
      internalFrame.setBorder(null);  
      internalFrame.getContentPane().add(buildCenterPane());  
      internalFrame.setSize(new Dimension(200, 200)); 
      internalFrame.setLocation(0, 0); 
      internalFrame.setResizable(false); 
      internalFrame.setVisible(true); 
     } 

     private JPanel buildCenterPane(){ 
      JPanel panel = new JPanel(); 
      panel.setLayout(new BorderLayout()); 
      layeredPane = new JLayeredPane(); 
      Position shelfPosition = new Position(0,0,200,200); 
      setLayeredPaneSize(shelfPosition); 
      JLabel label = getImageLabel(getImage("duke.png"), 
       new Position(0,0,100,100));   
      layeredPane.add(label, Integer.valueOf(LAYER1));   
      label = getImageLabel(getImage("arrowToLeft.gif"), 
       new Position(100,100,50,50));  
      layeredPane.add(label, Integer.valueOf(LAYER2)); 
      label = getImageLabel(getImage("arrowToRight.gif"), 
       new Position(50,50,50,50));  
      layeredPane.add(label, Integer.valueOf(LAYER3));   
      scrollPane = new JScrollPane(layeredPane);  
      panel.add(scrollPane, BorderLayout.CENTER); 
      panel.add(getSliderPane(), BorderLayout.SOUTH);  
      return panel; 
     } 

     private Image getImage(String key){ 
    InputStream is = this.getClass().getResourceAsStream(key); 
    try { 
     return ImageIO.read(is); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
    return null; 
     } 

     private void setLayeredPaneSize(Position shelfPosition){ 
      int width = (int)(shelfPosition.getWidth() * scaleFactor + 10); 
      int height = (int)(shelfPosition.getHeight() * scaleFactor + 10); 
      layeredPane.setPreferredSize(new Dimension(width,height)); 
     } 

     public void zoom(double factor){ 
      if (factor < MIN_ZOOM_VALUE) 
       factor = MIN_ZOOM_VALUE; 
      else if (factor > MAX_ZOOM_VALUE) 
       factor = MAX_ZOOM_VALUE; 
      scaleFactor = factor; 
      Position shelfPosition = new Position(0,0,200,200); 
      setLayeredPaneSize(shelfPosition);   
      scrollPane.getViewport().repaint(); 
      scrollPane.repaint();   
      scrollPane.getViewport().revalidate(); 
      scrollPane.revalidate(); 
     } 

     private JLabel getImageLabel(Image image, Position position) { 
      position = position.moveInRatio(scaleFactor); 
      ImageLabel label = new ImageLabel(new ImageIcon(image), position); 
      label.setOpaque(false); 
      label.setBounds(position.getLeft(), 
       position.getTop(),position.getWidth(),position.getHeight()); 
      return label; 
     } 

     private JPanel getSliderPane(){ 
      JPanel outer = new JPanel(); 
      outer.setLayout(new FlowLayout());  
      JPanel panel = new JPanel(); 
      panel.setLayout(new BorderLayout()); 
      final JSlider slider = new JSlider((int) (MIN_ZOOM_VALUE * 100), 
       (int) (MAX_ZOOM_VALUE * 100), 100); 
      slider.setMajorTickSpacing(1); 
      slider.setMinorTickSpacing(1); 
      double sliderValue = scaleFactor * 100.0; 
      slider.setValue((int) sliderValue); 
      slider.addChangeListener(new ChangeListener() {   
     @Override 
     public void stateChanged(ChangeEvent e) { 
      scaleFactor = slider.getValue()/100.0; 
      zoom(scaleFactor); 

     } 
    }); 
      panel.add(slider, BorderLayout.CENTER);   
      outer.add(panel); 
      return outer; 
     } 

     public static void main(String...strings){ 
      JFrame frame = new JFrame("FrameDemo"); 
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      frame.getContentPane().add(new LayeredPaneTest().getView(), 
       BorderLayout.CENTER); 
      frame.pack(); 
      frame.setVisible(true); 
     } 

     static class Position{ 
      private final int left,top,width,height; 

      Position(int x1, int y1, int x2, int y2){ 
       this.left = x1; 
       this.top = y1; 
       this.width = x2; 
       this.height = y2; 
       } 

       public int getLeft() { 
      return left; 
     } 

     public int getTop() { 
      return top; 
     } 

     public int getWidth() { 
      return width; 
     } 

     public int getHeight() { 
      return height; 
     }  
     } 

     private class ImageLabel extends JLabel{ 
      private static final long serialVersionUID = 6152144095443433296L; 
      private ImageIcon image; 
      private Position position; 

      public ImageLabel(ImageIcon image, Position position){ 
      super(image); 
      this.image = image; 
      this.position = position; 
      } 

      public void paintComponent(Graphics g) { 
      int newX = (int)(position.getLeft() * scaleFactor); 
      int newY = (int)(position.getTop() * scaleFactor);   
      Graphics2D g2 = (Graphics2D)g; 
      int newW = (int)(position.getWidth() * scaleFactor); 
      int newH = (int)(position.getHeight() * scaleFactor); 
      setBounds(newX, newY, newW, newH); 
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
        RenderingHints.VALUE_ANTIALIAS_ON); 
      g2.drawImage(image.getImage(), 0, 0, newW, newH, null); 
      } 
     } 

} 

但是,這裏的問題是,當我放大一次並縮小時,一些圖像消失。任何想法爲什麼它的行爲如此?

以下是重現錯誤的步驟; a。將滑塊拖動到最大值 b。看到圖像被擴展到最大值並且滾動條被引入, c。現在幾乎沒有圖像的部分被隱藏, d。現在將滑動條拖到最小值。 e。圖像的隱藏部分消失。

+4

爲了更好地爲您提供幫助,請發佈[SSCCE](http://sscce.org) –

回答

1

你不通過調用super.XXX實現覆蓋paintComponent方法,像這樣孝敬油漆鏈

@Override 
protected void paintComponent(Graphics grphcs) { 
    super.paintComponent(grphcs); 

    //do the rest of the painting here 
} 

由於the docs明確規定:

如果不調用超類的實現你必須尊重不透明 屬性,即如果此組件是不透明的,則必須完全在 後面填寫一個no不透明的顏色。如果您不尊重 不透明屬性,您可能會看到視覺工件。

還要注意@Override註釋,以確保我重寫了正確的方法,並且默認paintComponentprotected保持這種狀態,你不想暴露這種方法與其他類應該使用repaint()

+1

+1好用的文檔! – MadProgrammer

+0

在您提到的更改後仍然無法正常工作。用SSCCE更新了這個問題。 – user1931801