【问题标题】:Java JScrollPane- Multiple componentsJava JScrollPane - 多个组件
【发布时间】:2011-04-30 06:38:53
【问题描述】:

我正在尝试在 JScrollPane 中添加 2 个图像。第一个图像是背景,第二个与第一个重叠。当我运行我的程序时,问题只显示第二张图片!

请帮忙

ImageIcon ii = new ImageIcon("mini_map.png");
JLabel label1=new JLabel(ii);

Icon icon = new ImageIcon("Mg.gif");
JLabel label2 = new JLabel(icon);

JScrollPane jsp=new JScrollPane();

jsp.getViewport().add(label1);
jsp.getViewport().add(label2 );

【问题讨论】:

    标签: java swing jscrollpane


    【解决方案1】:

    JViewport 是单子容器,不能添加两个组件。

    要在 any 容器中实现重叠(即在 z 方向上堆叠组件),您主要靠自己,内置支持很差。要么必须在 LayeredPane 中管理它们(如前所述),要么尝试 OverlapLayout

    【讨论】:

    • +1 @kleopatra OverlapLayout 看起来是一个非常有用的管理器。谢谢我不知道。它可以很好地解决这个问题。
    【解决方案2】:

    将两个标签放在同一个面板中,并将其添加到 JScrollPane:

    ImageIcon ii = new ImageIcon("mini_map.png");
    JLabel label1=new JLabel(ii);
    
    Icon icon = new ImageIcon("Mg.gif");
    JLabel label2 = new JLabel(icon);
    
    JPanel pContainer = new JPanel();
    pContainer.add(label1);
    pContainer.add(label2);
    JScrollPane jsp=new JScrollPane(pContainer);
    

    【讨论】:

    • 这将使组件在彼此旁边或上方/下方对齐,而不是满足“重叠”要求。
    • 这是真的,我错过了写他希望它们重叠的部分,但他不能将 2 个组件分配给 JScrollPane。
    • "..missed the part.." 有时我忙于将未格式化代码的狗早餐帖子编辑成可读的内容,以至于我会错过细微的细节。难以区分“森林与树木”。 ;) 顺便说一句,感谢您使帖子具有可读性,以便其他人(例如我)可以发现这些更精细的细节。 :)
    • 标题没有提到重叠要求,我也没有谷歌搜索重叠的东西,所以 +1 回答了我是 Googlig 的目的。
    【解决方案3】:

    如果您想让组件相互叠加,请使用layered pane。

    【讨论】:

      【解决方案4】:

      对于您的特定问题,我会这样做。

      既然你说你有一张图片充当背景,所以我会像下面的 BackgroundPanel 那样覆盖paintComponent()。 这样,您就有了一个仅用作背景的面板。您可以向它添加任何类型的组件,在您的情况下是带有 ImageIcon 的 JLabel。

      这样你就有了一个超越另一个的效果,你仍然可以使用布局管理器来控制你的组件在哪里。

      如果您的问题更复杂,或者您希望通常将组件设置在另一个之上,那么按照这里所说的执行 ---> 使用 JLayeredPane。请注意,如果您遗憾地使用 JLayeredPane,布局管理器不会帮助您,因为它不尊重它们。当您使用 null 管理器时,您将不得不进行类似的处理,即 setBounds() 用于组件。

      import java.awt.BorderLayout;
      import java.awt.Dimension;
      import java.awt.Graphics;
      import java.awt.Graphics2D;
      import java.awt.Image;
      import java.awt.RenderingHints;
      import java.net.MalformedURLException;
      import java.net.URL;
      import java.util.logging.Level;
      import java.util.logging.Logger;
      import javax.swing.ImageIcon;
      import javax.swing.JFrame;
      import javax.swing.JLabel;
      import javax.swing.JPanel;
      import javax.swing.JScrollPane;
      import javax.swing.SwingUtilities;
      
      public class PaintInScroll
      {
          public static void main(String[] args)
          {
              SwingUtilities.invokeLater(new Runnable()
              {
                  @Override
                  public void run()
                  {
                      try
                      {
                          Image backgroundImage = new ImageIcon(new URL(
                                  "http://www.jvsearch.com/adidocs7_images/JAVAORANGE.JPG")).getImage();
                          BackgroundPanel bP = new BackgroundPanel(backgroundImage);
                          bP.setLayout(new BorderLayout());
                          bP.setPreferredSize(new Dimension(500, 500));
                          JLabel label = new JLabel(new ImageIcon(new URL(
                                  "https://blogs.oracle.com/theplanetarium/resource/thumb-java-duke-guitar.png")));
                          bP.add(label, BorderLayout.CENTER);
                          JScrollPane scrollPane = new JScrollPane(bP);
                          scrollPane.setPreferredSize(new Dimension(300, 400));
                          JPanel contentPane = new JPanel();
                          contentPane.add(scrollPane);
                          JFrame f = new JFrame();
                          f.setContentPane(contentPane);
                          f.setSize(800, 600);
                          f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                          f.setVisible(true);
                      }catch(MalformedURLException ex)
                      {
                          Logger.getLogger(PaintInScroll.class.getName()).log(Level.SEVERE, null, ex);
                      }
                  }
              });
          }
      }
      
      class BackgroundPanel extends JPanel
      {
          private Image image;
      
          public BackgroundPanel(Image image)
          {
              this.image = image;
          }
          private static final long serialVersionUID = 1L;
      
          @Override
          protected void paintComponent(Graphics g)
          {
              super.paintComponent(g);
              Graphics2D g2 = (Graphics2D) g;
              g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
              g2.drawImage(image, 0, 0, this.getWidth(), this.getHeight(), null);
          }
      }
      

      注意:图像是 URL,因此运行示例需要 i-net 连接。

      EDIT1:示例展示了如何将 JLayeredPane 与每一层的布局管理器一起使用。

      import java.awt.BorderLayout;
      import java.awt.Component;
      import java.awt.Dimension;
      import java.awt.event.ComponentAdapter;
      import java.awt.event.ComponentEvent;
      import java.awt.event.ComponentListener;
      import java.net.MalformedURLException;
      import java.net.URL;
      import java.util.logging.Level;
      import java.util.logging.Logger;
      import javax.swing.ImageIcon;
      import javax.swing.JButton;
      import javax.swing.JFrame;
      import javax.swing.JLabel;
      import javax.swing.JLayeredPane;
      import javax.swing.JPanel;
      import javax.swing.JScrollPane;
      import javax.swing.SwingUtilities;
      
      public class PaintInScrollRespectingLayoutManagers extends JPanel
      {
          private static final long serialVersionUID = 1L;
          private JLayeredPane layeredPane;
          private JLabel imageContainer = new JLabel();
          private JButton infoB = new JButton("i");
          private JScrollPane scrollPane;
      
          public PaintInScrollRespectingLayoutManagers(ImageIcon image)
          {
              super();
              this.imageContainer.setIcon(image);
              scrollPane = new JScrollPane(imageContainer);
              scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
              scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
              scrollPane.setPreferredSize(new Dimension(125, 90));
              JPanel iSPP = new JPanel();//image scroll pane panel
              iSPP.setOpaque(false);
              iSPP.add(scrollPane);
              JPanel iBP = new JPanel();//info button panel
              iBP.setOpaque(false);
              iBP.add(infoB);
              this.layeredPane = new JLayeredPane();
              layeredPane.add(iSPP, new Integer(50));
              layeredPane.add(iBP, new Integer(100));
              this.setLayout(new BorderLayout());
              this.add(layeredPane, BorderLayout.CENTER);
              this.add(new JButton("A button"), BorderLayout.SOUTH);
              layeredPane.addComponentListener(layeredPaneCL);
              setPreferredSize(new Dimension(300, 300));
          }
          private ComponentListener layeredPaneCL = new ComponentAdapter()
          {
              @Override
              public void componentResized(ComponentEvent e)
              {
                  super.componentResized(e);
                  System.out.println("componentResized");
                  for(Component c : layeredPane.getComponents())
                      c.setSize(layeredPane.getSize());
              }
          };
      
          public static void main(String[] args)
          {
              SwingUtilities.invokeLater(new Runnable()
              {
                  @Override
                  public void run()
                  {
                      try
                      {
                          JFrame frame = new JFrame();
                          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                          frame.add(new PaintInScrollRespectingLayoutManagers(new ImageIcon(new URL(
                                  "http://www.prodeveloper.org/wp-content/uploads/2008/10/stackoverflow-logo-250.png"))));
                          frame.pack();
                          frame.setVisible(true);
                      }catch(MalformedURLException ex)
                      {
                          Logger.getLogger(PaintInScrollRespectingLayoutManagers.class.getName()).log(Level.SEVERE, null, ex);
                      }
                  }
              });
          }
      }
      

      注意 2: 滚动窗格具有 setPreferedSize 的唯一原因是您可以看到滚动条。否则不要使用它,让布局负责控制滚动窗格。

      【讨论】:

        猜你喜欢
        • 2014-03-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多