Java JScrollPane-多个组件

我正在尝试在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 ); 

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

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

如果要将组件放在彼此之上,请使用分层窗格 。

将两个标签放在同一个面板中并将其添加到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); 

这就是我如何为您的特定问题做到这一点。

既然你说你有一个图像作为背景的角色,那么我会覆盖paintComponent(),如下面的BackgroundPanel。 这样你就有了一个仅作为背景的面板。 对于它,您可以添加任何类型的组件,在您的情况下是带有ImageIcon的JLabel。

通过这种方式,您可以使用布局管理器来控制组件的位置。

如果您的问题更复杂,或者您希望一般将组件设置为另一个,那么就像所有人在这里说的那样—>使用JLayeredPane。 请注意,如果您使用JLayeredPane,布局管理器将无法帮助您,因为它不尊重它们。 您必须类似于使用空管理器的情况,即组件的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://sofzh.miximages.com/java/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://sofzh.miximages.com/java/stackoverflow-logo-250.png")))); frame.pack(); frame.setVisible(true); }catch(MalformedURLException ex) { Logger.getLogger(PaintInScrollRespectingLayoutManagers.class.getName()).log(Level.SEVERE, null, ex); } } }); } } 

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